17

私はクラスを持っています:

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

実行時にこのクラスにプロパティ/フィールドを追加することは可能ですか?

(コンパイル時の型や名前がわからず、使用できる共通のインターフェイスがありません。 )

擬似例:

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

私はすでにこの質問を読みましたが、インターフェースを使用しています

前もって感謝します。

4

3 に答える 3

45

実行時に新しいメンバーで既存のクラスを拡張することはできません。ただし、既存のクラスを基本クラスとして持つSystem.Reflection.Emitを使用して、新しいクラスを作成できます。

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

完全な例については、TypeBuilder.DefineProperty メソッド (String、PropertyAttributes、Type、Type[])を参照してください。

于 2013-02-06T08:47:08.437 に答える
6

あなたは反射とは何かを誤解していると思います。リフレクションでは、実行しているコードを変更することはできません。独自のコードを読み取ったり、そのコードを実行したりすることもできます。

Reflection.Emitを使用すると、まったく新しいアセンブリを作成して、それをメモリにロードできます。

ただし、実行時にクラスを変更することはできません。想像してみてください。あなたはクラスFooを持っていて、それらの束全体をインスタンス化してから、クラスを変更することにしました。

あなたがすでにインスタンス化したすべてのFoosはどうなりますか?

ただし、Reflection.Emitを使用して、Fooを継承するBarという新しいクラスを作成し、必要なものをそのクラスに追加することができます。

または、コンパイル時の後、実行時より前にプログラムでクラスにプロパティを追加する場合は、IL Weaving/AOPを確認できます。これがあなたが興味を持っているものであるならば、私はPostSharpまたはFodyを見ることを提案します。

于 2013-02-06T09:09:32.620 に答える
2

はい、ExpandoObjectクラスを使用してこれを実現できます。

dynamic expando = new ExpandoObject();
expando.Prop1 = 10;
expando.Prop900 = string.Empty;
于 2013-02-06T08:45:20.220 に答える