2013-02-06 78 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如果這是你感興趣的。

相關問題