2013-02-06 7 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

私はそれを成功させました。ありがとう。 (それは道だった)。実際の質問をお寄せいただきありがとうございます。 –

+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を参照してください。興味があるのであれば、PostSharpまたはFodyを見ることをお勧めします。

関連する問題