2013-02-06 55 views
8

我有一个类:如何在C#中将运行时属性添加到类中?

class MyClass 
{ 
} 
... 
MyClass c = new MyClass(); 

是否有可能将属性/字段添加到这个类在运行时?

我不知道他们有什么类型或编译时的名字和他们没有共同的界面,我可以使用)。

伪例如:

Add property named "Prop1" [type System.Int32] 
Add property named "Prop900" [type System.String] 

我已经阅读this question,但它使用接口

在此先感谢。

+2

然后通过反射来访问它们到处?如何处理'Dictionary '? –

+0

@HenkHolterman是的Henk后来我用'MyClass.GetType()来访问它们。GetProperties()' –

+1

你需要什么样的用例?那么'ICustomeTypeDescriptor'呢? – Dennis

回答

24

您不能在运行时使用新成员来扩展现有的类。但是,您可以使用System.Reflection.Emit创建一个具有现有类作为基类的新类。

typeBuilder.SetParent(typeof(MyClass)); 
typeBuilder.DefineProperty("Prop1", ..., typeof(System.Int32), null); 
... 

查看TypeBuilder.DefineProperty Method (String, PropertyAttributes, Type, Type[])查看完整示例。

+0

看起来很有趣。我会看看谢谢。 –

+0

我已经成功了。谢谢。 (就是这样)。感谢_answering_的实际问题。 –

+0

很好的解释,它也适用于我.. –

1

是的,您可以使用ExpandoObject类来实现此目的。

dynamic expando = new ExpandoObject(); 
expando.Prop1 = 10; 
expando.Prop900 = string.Empty; 
+1

它使用里面的字典实现。我需要具有属性的纯类。 –

+1

@RoyiNamir:为什么? –

+0

'GetType()。GetProperties()'可能比字典效率低。 –

4

我想你已经误解了反射是什么。反射不允许您更改正在运行的代码。它可以让你阅读你自己的代码,甚至运行该代码。

使用Reflection.Emit,您可以编写一个全新的程序集,然后将其加载到内存中。

但是,您不能在运行时更改类。想象一下,你有一个班级Foo,你将其中的一大堆实例化,然后决定改变班级。

您已经实现的所有Foos应该发生什么?

但是,您可以使用Reflection.Emit创建一个继承Foo的新类,名为Bar,然后将该类所需的任何内容添加到该类中。

或者,如果您希望以编程方式在编译时间之后但在运行时之前向类中添加属性,则可以查看IL编织/ AOP。我建议看看PostSharpFody如果这是你感兴趣的。

相关问题