我有一个班级:
class MyClass
{
}
...
MyClass c = new MyClass();
是否可以在运行时向此类添加属性/字段?
(我不知道它们在编译时的类型或名称是什么,它们没有我可以使用的通用接口。)
psuedo示例:
Add property named "Prop1" [type System.Int32]
Add property named "Prop900" [type System.String]
我已阅读this question但它使用了界面
提前致谢。
答案 0 :(得分:29)
您无法在运行时使用新成员扩展现有类。但是,您可以使用System.Reflection.Emit创建一个新类,该类具有现有类作为基类。
typeBuilder.SetParent(typeof(MyClass));
typeBuilder.DefineProperty("Prop1", ..., typeof(System.Int32), null);
...
有关完整示例,请参阅TypeBuilder.DefineProperty Method (String, PropertyAttributes, Type, Type[])。
答案 1 :(得分:4)
我认为你误解了反映是什么。反射不允许您更改正在运行的代码。它可以让您阅读自己的代码甚至运行该代码。
使用Reflection.Emit,您可以编写一个全新的程序集,然后将其加载到内存中。
但是,您无法在运行时更改类。想象一下,你有一个Foo类,你实现了一大堆,然后决定改变这个类。
你已经实施过的所有Foos会发生什么?
但是,您可以使用Reflection.Emit创建一个继承Foo的新类,称为Bar,然后向该类添加所需的任何内容。
或者,如果要在编译时间之后以编程方式将属性添加到类,但在运行时之前,可以查看IL Weaving / AOP。如果您对此感兴趣,我建议您查看PostSharp或Fody。
答案 2 :(得分:1)
是的,您可以使用ExpandoObject
类来实现此目的。
dynamic expando = new ExpandoObject();
expando.Prop1 = 10;
expando.Prop900 = string.Empty;