运行时通过字符串修改DynamicObject派生类内部字典的问题及实现方案
常规反射方案失效的原因
反射的底层逻辑是读取类型在CLR中存储的静态元数据,仅能获取到类定义阶段显式声明的属性、字段、方法等成员。
你当前实现的DynamicModuleBase的动态属性本质是靠重写DynamicObject的绑定方法,用内部字典在运行时模拟出来的虚拟成员,并没有在类型元数据中生成对应的PropertyInfo条目,因此GetProperty必然返回null。
另外你将实例转为dynamic的操作也不会改变反射结果:dynamic仅影响编译期的绑定逻辑,GetType()返回的始终是实例的实际运行时类型DynamicModuleBase的元数据,不会包含动态添加的属性信息。
正确实现方式
场景1:可修改DynamicModuleBase源码(推荐)
直接给类添加索引器封装内部字典的读写,是性能最高、维护成本最低的方案:
public class DynamicModuleBase : DynamicObject, IModuleBase { Dictionary<string, object> DynamicProperties = new Dictionary<string, object>(); // 新增索引器 public object this[string propertyName] { get => DynamicProperties[propertyName]; set => DynamicProperties[propertyName] = value; } // 其余原有代码保持不变 }
后续直接通过字符串键读写即可:
// 读 var value = myObjectInstance[myPropertyNameAsString]; // 写/新增 myObjectInstance[myPropertyNameAsString] = "要设置的值";
场景2:无法修改DynamicModuleBase源码
可以通过反射读取类的私有字段DynamicProperties,直接操作字典实现读写:
using System.Reflection; // 读取私有字典字段 var dictField = typeof(DynamicModuleBase).GetField("DynamicProperties", BindingFlags.Instance | BindingFlags.NonPublic); var dynamicDict = (Dictionary<string, object>)dictField.GetValue(myObjectInstance); // 读取属性值 if (dynamicDict.TryGetValue(myPropertyNameAsString, out var propertyValue)) { // 处理读取到的属性值 } // 写入/新增属性 dynamicDict[myPropertyNameAsString] = "要设置的值";
内容的提问来源于stack exchange,提问作者stackMeUp
相关产品推荐
相关产品推荐

