如何用System.Reflection的SetValue/InvokeMember为myClass对象字段赋值?
如何通过反射为嵌套类字段赋值(FieldInfo.SetValue & Type.InvokeMember)
咱们一步一步拆解你的需求:你要通过字符串指定字段名和值,给myClass2里嵌套的myClass对象的字段赋值,用到FieldInfo.SetValue和Type.InvokeMember两种反射方式。核心是先拿到内层myClass的实例引用,再对它的字段进行操作。
先看完整的可运行代码示例,把你代码里的??????替换成正确参数:
using System; using System.Reflection; namespace ConsoleApp2 { class myClass { public string obj1; public string obj2; } class myClass2 { public myClass obj = new myClass(); } class Program { static void Main(string[] args) { // 获取myClass2的类型 Type type = Type.GetType("ConsoleApp2.myClass2"); // 创建myClass2的实例 object classObj = Activator.CreateInstance(type); // ========== 用FieldInfo.SetValue的方式赋值 ========== // 获取myClass2中"obj"字段的FieldInfo FieldInfo fi = type.GetField("obj"); // 先拿到myClass的实例(从classObj的obj字段中获取) object innerMyClassObj = fi.GetValue(classObj); // 用字符串指定要赋值的字段名和值 string targetFieldName = "obj1"; string targetValue = "我是通过SetValue赋值的obj1"; // 获取myClass中目标字段的FieldInfo FieldInfo innerField = innerMyClassObj.GetType().GetField(targetFieldName); // 给目标字段赋值:第一个参数是要操作的对象,第二个是要设置的值 innerField.SetValue(innerMyClassObj, targetValue); // ========== 用Type.InvokeMember的方式赋值 ========== string anotherFieldName = "obj2"; string anotherValue = "我是通过InvokeMember赋值的obj2"; // 调用innerMyClassObj的类型的InvokeMember方法 innerMyClassObj.GetType().InvokeMember( anotherFieldName, // 字符串指定的目标字段名 BindingFlags.SetField | BindingFlags.Public | BindingFlags.Instance, // 绑定标志:设置公共实例字段 null, // 绑定器,通常传null即可 innerMyClassObj, // 要操作的目标对象(myClass实例) new object[] { anotherValue } // 参数数组:存放要设置的字段值 ); // 验证赋值结果 myClass2 typedObj = (myClass2)classObj; Console.WriteLine($"obj1的值:{typedObj.obj.obj1}"); Console.WriteLine($"obj2的值:{typedObj.obj.obj2}"); } } }
关键参数细节解释
1. FieldInfo.SetValue的参数
- 第一个参数:
innerMyClassObj,要设置字段的目标对象(这里是myClass的实例,不是外层myClass2的实例)。 - 第二个参数:
targetValue,要给字段设置的具体值,注意类型要和字段类型匹配(这里都是string,完全兼容)。
2. Type.InvokeMember的参数
- 第一个参数:
anotherFieldName,字符串形式的目标字段名,就是你要赋值的字段的名称。 - 第二个参数:
BindingFlags.SetField | BindingFlags.Public | BindingFlags.Instance,绑定标志组合,明确告诉反射我们要操作的是公共的实例字段,并且是执行设置操作。 - 第三个参数:
null,一般不需要自定义绑定器,直接传null就行。 - 第四个参数:
innerMyClassObj,要操作的目标对象(必须是myClass的实例,因为我们要给它的字段赋值)。 - 第五个参数:
new object[] { anotherValue },参数数组,因为设置字段只需要传入值,所以数组里放要设置的内容即可。
额外注意点
如果你的需求是直接给myClass2的obj字段本身赋值(而非它的子字段),那写法会更简单:fi.SetValue(classObj, new myClass { obj1 = "直接替换整个obj字段" }),此时第一个参数是classObj(myClass2的实例),第二个参数是新的myClass对象。
内容的提问来源于stack exchange,提问作者muhayyuddin gillani
相关产品推荐
相关产品推荐

