有没有办法在运行时向类添加Field
(或FieldInfo
,或许这是相同的)?
答案 0 :(得分:25)
您无法在运行时更改类定义。但是,您可以创建一个继承自原始类的新类(如果它不是sealed
)并声明该字段。您可以通过使用System.Reflection.Emit
答案 1 :(得分:7)
C#不允许它,因为它的所有类都基于元数据。 CLR (不是C#)不允许在运行时向元数据添加字段(1)。这是C#能够在runitme添加字段的唯一方法。
这与IronPython等动态语言不同,后者基本上没有具体的元数据类。它们具有更多动态结构,可以在运行时更改。我相信IronPython只是将它的成员(字段和方法)保留在可以在运行时轻松更改的哈希表中。
在C#3.0中,您最好的资源是使用Reflection.Emit。但是这会产生一个全新的类而不是改变现有的类。
(1)某些API(例如分析API或ENC)允许这样做,但我不确定它们的功能是否扩展到添加字段。
答案 2 :(得分:6)
不,C#不允许monkey-patching。
您可以使用CodeDOM或Reflection.Emit生成 new 类,但不能修改现有的类。
答案 3 :(得分:1)
不完全是。
但是,您可以实现ICustomTypeDescriptor来近似它,然后只使用哈希表来存储字段名/值对。很多使用反射的框架首先要求ICustomTypeDescriptor。
答案 4 :(得分:1)
直到C#4.0添加动态查找并且基于包含DLR的CLR 4.0,然后它不会严格地添加到类中,因为类不在图片中。
答案 5 :(得分:1)
class My {
Dictionary<string, object> data;
public My() { data = new Dictionary<string, object>(); }
}
..但这实际上取决于你真正想要实现的目标?
答案 6 :(得分:1)
通过将ExpandoObject
强制转换为IDictionary
,请参阅this question以了解在C#4.0中执行此操作的简单方法,这会导致添加到字典中的值成为对象的属性。我在another answer of mine中证明了这一点,表明它们实际上已成为属性。
但是,这仅适用于ExpandoObject
的实例或通过子类DynamicObject
实现。
如果它们实现IDynamicMetaObjectProvider
,也可以与其他类一起使用,但我认为有太多的工作要让它正常工作。
答案 7 :(得分:0)
也许您可以使用装饰器模式。
在面向对象的编程中,装饰器模式是一种设计模式,它允许将行为静态或动态地添加到单个对象,而不会影响同一类中其他对象的行为。