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}"); } } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。