web-dev-qa-db-ja.com

C#で実行時にクラスにプロパティを追加する方法はありますか

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

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

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

コンパイル時のタイプまたは名前がわからないため、使用できる共通のインターフェイスがありません。

疑似例:

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

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

前もって感謝します。

15
Royi Namir

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

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

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

32
dtb

リフレクションとは何か誤解されていると思います。 Reflectionでは、実行中のコードを変更することはできません。独自のコードを読み取って、そのコードを実行することもできます。

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

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

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

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

または、コンパイル時の後、実行前にクラスにプログラムでプロパティを追加する場合は、ILウィービング/ AOPを確認できます。これがあなたが興味を持っているものである場合、私は PostSharp または Fody を参照することをお勧めします。

5
Aron

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

dynamic expando = new ExpandoObject();
expando.Prop1 = 10;
expando.Prop900 = string.Empty;
2
Daniel Hilgarth