C# 通过反射获取类型的字段值及给字段赋值的操作
举例:
存在一个类:
PublicClassStudent
{
publicstringname;
publicintage;
}
Studentstu1=newStudent();
现在,我们想通过反射在运行时给stu1的name和age字段赋值,让name=“小明”,age=15,怎么做?
简单的代码如下:
...略
usingSystem.Reflection;//反射类
...略
staticvoidMain(string[]args)
{
Typet=stu1.GetType();
FieldInfofiledInfo1=t.GetField(”name");
FieldInfofiledInfo2=t.GetField(”age");
fieldInfo1.SetValue(stu1,"小明");
fieldInfo2.SetValue(stu1,15);
}
需要注意的是:FieldInfo的SetValue方法有可能会导致异常,比如fieldInfo2.SetValue(stu1,“15”),这句话给一个int型字段赋了string类型的值,编译是不会报错的,在运行时会抛出一个System.ArgumentException异常,请多加注意.
有了以上的了解,让我们写一个简单的动态字段赋值/取值类Dynamic
具体代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Reflection;
namespaceMyUnityHelper
{
///
///动态编译类
///
publicclassDynamic
{
///
///动态赋值
///
///
///
///
publicstaticvoidSetValue(objectobj,stringfieldName,objectvalue)
{
FieldInfoinfo=obj.GetType().GetField(fieldName);
info.SetValue(obj,value);
}
///
///泛型动态赋值
///
///
///
///
///
publicstaticvoidSetValue(objectobj,stringfieldName,Tvalue)
{
FieldInfoinfo=obj.GetType().GetField(fieldName);
info.SetValue(obj,value);
}
///
///动态取值
///
///
///
///
publicstaticobjectGetValue(objectobj,stringfieldName)
{
FieldInfoinfo=obj.GetType().GetField(fieldName);
returninfo.GetValue(obj);
}
///
///动态取值泛型
///
///
///
///
///
publicstaticTGetValue(objectobj,stringfieldName)
{
FieldInfoinfo=obj.GetType().GetField(fieldName);
return(T)info.GetValue(obj);
}
}
}
补充:C#利用反射方法实现对象的字段和属性之间值传递
在面向对象开发过程中,往往会遇到两个对象之间进行值传递的情况,如果对象中的属性和字段较多,手动一一赋值效率实在太低。
这里就整理了一个通用的对象之间进行值传递的方法,并且考虑到对象中可能包含类属性,因此还用到了递归以解决这个问题。
下面上代码:
publicstaticvoidConvertObject(objectSrcClass,objectDesClass,boolconvertProperty=true,boolconvertField=true,boolshowError=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(varsrcPiinsrcProperties)
{
foreach(vardesPiindesProperties)
{
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
{
Objectvalue=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(varsrcFieldinsrcFields)
{
foreach(vardesFieldindesFields)
{
if(srcField.Name==desField.Name&&srcField.FieldType==desField.FieldType)
{
if(srcField.FieldType.IsClass)
{
ConvertObject(srcField.GetValue(SrcClass),desField.GetValue(DesClass),convertProperty,convertField,showError);
}
else
{
Objectvalue=srcField.GetValue(SrcClass);
desField.SetValue(DesClass,value);
}
}
}
}
}
}
}
catch(Exceptionex)
{
if(showError)
{
MessageBox.Show($"ConvertError:Method={nameof(ConvertObject)},Message={ex.Message}");
}
else
{
thrownewException($"ConvertError:Method={nameof(ConvertObject)},Message={ex.Message}");
}
}
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。