C# 通過反射獲取類型的字段值及給字段賦值的操作
舉例:
存在一個(gè)類:
Public Class Student { public string name; public int age; } Student stu1 = new Student();
現(xiàn)在,我們想通過反射在運(yùn)行時(shí)給stu1的name 和 age字段 賦值,讓name = “小明”,age = 15,怎么做?
簡(jiǎn)單的代碼如下:
...略 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方法有可能會(huì)導(dǎo)致異常,比如 fieldInfo2.SetValue(stu1,“15”),這句話給一個(gè)int型字段賦了string類型的值,編譯是不會(huì)報(bào)錯(cuò)的,在運(yùn)行時(shí)會(huì)拋出一個(gè)System.ArgumentException異常,請(qǐng)多加注意.
有了以上的了解,讓我們寫一個(gè)簡(jiǎn)單的動(dòng)態(tài)字段賦值/取值類Dynamic
具體代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; namespace MyUnityHelper { /// <summary> /// 動(dòng)態(tài)編譯類 /// </summary> public class Dynamic { /// <summary> /// 動(dòng)態(tài)賦值 /// </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> /// 泛型動(dòng)態(tài)賦值 /// </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> /// 動(dòng)態(tài)取值 /// </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> /// 動(dòng)態(tài)取值泛型 /// </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); } } }
補(bǔ)充:C#利用反射方法實(shí)現(xiàn)對(duì)象的字段和屬性之間值傳遞
在面向?qū)ο箝_發(fā)過程中,往往會(huì)遇到兩個(gè)對(duì)象之間進(jìn)行值傳遞的情況,如果對(duì)象中的屬性和字段較多,手動(dòng)一一賦值效率實(shí)在太低。
這里就整理了一個(gè)通用的對(duì)象之間進(jìn)行值傳遞的方法,并且考慮到對(duì)象中可能包含類屬性,因此還用到了遞歸以解決這個(gè)問題。
下面上代碼:
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}"); } } }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
C# 如何在WINForm程序中創(chuàng)建XML文件
這篇文章主要介紹了C# 如何在WINForm程序中創(chuàng)建XML文件,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下2021-02-02WPF使用Dragablz構(gòu)建可拖拽分離的Tab頁(yè)程序
這篇文章介紹了WPF使用Dragablz構(gòu)建可拖拽分離Tab頁(yè)的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06在C#中使用OpenCV(使用OpenCVSharp)的實(shí)現(xiàn)
這篇文章主要介紹了在C#中使用OpenCV(使用OpenCVSharp)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11