C# 通过反射获取类型的字段值及给字段赋值的操作
作者:qq_40693302 发布时间:2021-11-14 13:30:23
标签:C#,反射,字段值,赋值
举例:
存在一个类:
Public Class Student
{
public string name;
public int age;
}
Student stu1 = new Student();
现在,我们想通过反射在运行时给stu1的name 和 age字段 赋值,让name = “小明”,age = 15,怎么做?
简单的代码如下:
...略
using System.Reflection;//反射类
...略
static void Main(string[] args)
{
Type t = stu1.GetType();
FieldInfo filedInfo1 = t.GetField(”name");
FieldInfo filedInfo2 = t.GetField(”age");
fieldInfo1.SetValue(stu1,"小明");
fieldInfo2.SetValue(stu1,15);
}
需要注意的是:FieldInfo的SetValue方法有可能会导致异常,比如 fieldInfo2.SetValue(stu1,“15”),这句话给一个int型字段赋了string类型的值,编译是不会报错的,在运行时会抛出一个System.ArgumentException异常,请多加注意.
有了以上的了解,让我们写一个简单的动态字段赋值/取值类Dynamic
具体代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace MyUnityHelper
{
/// <summary>
/// 动态编译类
/// </summary>
public class Dynamic
{
/// <summary>
/// 动态赋值
/// </summary>
/// <param name="obj"></param>
/// <param name="fieldName"></param>
/// <param name="value"></param>
public static void SetValue(object obj,string fieldName,object value)
{
FieldInfo info = obj.GetType().GetField(fieldName);
info.SetValue(obj, value);
}
/// <summary>
/// 泛型动态赋值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <param name="fieldName"></param>
/// <param name="value"></param>
public static void SetValue<T>(object obj, string fieldName, T value)
{
FieldInfo info = obj.GetType().GetField(fieldName);
info.SetValue(obj, value);
}
/// <summary>
/// 动态取值
/// </summary>
/// <param name="obj"></param>
/// <param name="fieldName"></param>
/// <returns></returns>
public static object GetValue(object obj, string fieldName)
{
FieldInfo info = obj.GetType().GetField(fieldName);
return info.GetValue(obj);
}
/// <summary>
/// 动态取值泛型
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <param name="fieldName"></param>
/// <returns></returns>
public static T GetValue<T>(object obj,string fieldName)
{
FieldInfo info = obj.GetType().GetField(fieldName);
return (T)info.GetValue(obj);
}
}
}
补充:C#利用反射方法实现对象的字段和属性之间值传递
在面向对象开发过程中,往往会遇到两个对象之间进行值传递的情况,如果对象中的属性和字段较多,手动一一赋值效率实在太低。
这里就整理了一个通用的对象之间进行值传递的方法,并且考虑到对象中可能包含类属性,因此还用到了递归以解决这个问题。
下面上代码:
public static void ConvertObject(object SrcClass, object DesClass, bool convertProperty = true, bool convertField = true, bool showError = true)
{
try
{
if (SrcClass == null)
{
return;
}
if (convertProperty)
{
PropertyInfo[] srcProperties = SrcClass.GetType().GetProperties();
PropertyInfo[] desProperties = DesClass.GetType().GetProperties();
if (srcProperties.Length > 0 && desProperties.Length > 0)
{
foreach (var srcPi in srcProperties)
{
foreach (var desPi in desProperties)
{
if (srcPi.Name == desPi.Name && srcPi.PropertyType == desPi.PropertyType && desPi.CanWrite)
{
if (srcPi.PropertyType.IsClass)
{
ConvertObject(srcPi.GetValue(SrcClass, null), desPi.GetValue(DesClass, null), convertProperty, convertField, showError);
}
else
{
Object value = srcPi.GetValue(SrcClass, null);
desPi.SetValue(DesClass, value, null);
}
}
}
}
}
}
if (convertField)
{
FieldInfo[] srcFields = SrcClass.GetType().GetFields();
FieldInfo[] desFields = DesClass.GetType().GetFields();
if (srcFields.Length > 0 && desFields.Length > 0)
{
foreach (var srcField in srcFields)
{
foreach (var desField in desFields)
{
if (srcField.Name == desField.Name && srcField.FieldType == desField.FieldType)
{
if (srcField.FieldType.IsClass)
{
ConvertObject(srcField.GetValue(SrcClass), desField.GetValue(DesClass), convertProperty, convertField, showError);
}
else
{
Object value = srcField.GetValue(SrcClass);
desField.SetValue(DesClass, value);
}
}
}
}
}
}
}
catch (Exception ex)
{
if (showError)
{
MessageBox.Show($"Convert Error: Method={nameof(ConvertObject)}, Message={ex.Message}");
}
else
{
throw new Exception($"Convert Error: Method={nameof(ConvertObject)}, Message={ex.Message}");
}
}
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。
来源:https://blog.csdn.net/qq_40693302/article/details/98961669


猜你喜欢
- 背景由于前前前阵子写了个壳,得去了解类的加载流程,当时记了一些潦草的笔记。这几天把这些东西简单梳理了一下,本文分析的代码基于Android8
- 目录一、抽象类1.抽象类概述1.1 为什么要有抽象类?(抽象类的作用)1.2 抽象类的定义2. 抽象类特点3.抽象类成员特点4.抽象类案例二
- 本篇文章主要介绍了java自动生成编号的实现,分享给大家,具体如下/** * 自动生成编号格式:yyMM+四位流水号 */ @Reques
- 1.前置准备默认服务器上的hadoop服务已经启动本地如果是windows环境,需要本地配置下hadoop的环境变量本地配置hadoop的环
- Docker现在很火,容器技术看上不无所不能,但这实际上是一种误解,不要被炒作出来的泡沫迷住双眼,本文抛去炒作,理性地从Java程序员的角度
- 简介这篇文章我一直在纠结到底要不要写,不想写一来因为定时器用法比较简单,二来是面试中也不常问。后来还是决定写了主要是想把自己分析问题思路分享
- 每次滑动至底端,从数据库中获取10条数据,并加载于ListView中数据库package com.example.listviewbatch
- 需求前台有日期字符串的数据,提交到后台。后台实体类使用Date属性接收。日期字符串有多种格式,需要用一个转换器将合法的日期字符串格式转换为D
- 一、使用线程的理由1、可以使用线程将代码同其他代码隔离,提高应用程序的可靠性。2、可以使用线程来简化编码。3、可以使用线程来实现并发执行。二
- 本文实例讲述了Android基于TextView实现的跑马灯效果。分享给大家供大家参考,具体如下:package sweet.venst.a
- Idea运行单个main方法,不编译整个工程直接上图1、选择main方法类右键->create ‘类名.main&
- 本文实例讲述了Android之复选框对话框用法。分享给大家供大家参考。具体如下:main.xml布局文件<?xml version=&
- SpringBoot 集成 activiti 基础环境搭建添加依赖<dependency> <groupId&g
- 在java 中需要设置三个环境变量(1.5之后不用再设置classpath了,但个人强烈建议继续设置以保证向下兼用问题)JDK安装完成之后我
- 一、负载均衡负载均衡(Load Balance): 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞
- 闲暇之余,开发一个图片编辑小程序。程序主要特点就是可方便的对多个图像编辑,实现了一些基本的操作。本文主要介绍一下程序的功能、设计思路。执行程
- 为了追求更好的用户体验,有时候我们需要一个类似心跳一样跳动着的控件来吸引用户的注意力,这是一个小小的优化需求,但是在 Flutter 里动画
- 实例如下:public String stripHtml(String content) { // <p>段落替换为换行 con
- Interfaces 接口在软件工程中,由一份“契约”规定来自不同的开发小组的软件之间如何相互作用是非常常见的。每个小组都可以在不知道别的组
- 由于GitHub上面的zxing功能太多,有的用不到,我就抽取了重要的出来使用,这个可以生成二维码,扫描二维码和相册中的二维码Demo效果: