2009-03-14 12 views

答えて

24

実行時にクラス定義を変更することはできません。ただし、元のクラス(sealedでない場合)から継承し、フィールドを宣言する新しいクラスを作成できます。これは、System.Reflection.Emitを使用して適切なILコードを放出することによって行うことができます。

6

いいえ、C#はmonkey-patchingを許可しません。

新しいクラスを生成するには、CodeDOMまたはReflection.Emitを使用しますが、既存のものは変更できません。

+1

サルパッチと呼ばれていますか?その言葉はどこから生じたのですか? –

+0

どこから来たのか分かりませんが、私はWikipediaエントリーへのリンクを追加しました。 –

+1

モンキーパッチはRubyに由来する用語です。ジェフアトウッドは、数年前にブログ記事でそれについて書きました。 –

1

正確ではありません。

しかし、ICustomTypeDescriptorを実装して近似し、ハッシュテーブルを使用してフィールド名と値のペアを格納するだけで済みます。リフレクションを使用するフレームワークの多くは、まずICustomTypeDescriptorを要求します。

+0

ありがとう、私はこのアプローチを試みたが、それは私のために働くdoesnt。私はimpellment IExpandoインターフェイスをJavaScriptコードが私のC#クラスのunexistedフィールドを呼び出すようにしようとしています。たとえば、 var o = new ActiveXObject( 'mCom'); o.ArbitraryField = "Foo"; 私のクラスではArbitraryFieldは存在しませんのでご注意ください。 –

+0

IReflectの実装を試しましたか?これは、動的言語(少なくともC#4.0より前のバージョン)で相互運用するためのIDispatch/IExpandoを実装する方法です。 http://msdn.microsoft.com/en-us/library/system.reflection.ireflect.aspx ハッシュテーブルの実装でこの正確なことを行いました。うまく動作します – codekaizen

1

ダイナミックルックアップを追加し、DLRを組み込んだCLR 4.0をベースにしているため、クラスが画像に含まれないため、厳密にはクラスに追加されません。

+0

これは可能だとは思いませんC#4.0では。私はあなたが既存のタイプを変更することはできないと思います。しかし、私はあなたが動的オブジェクト(例えば、Rubyから来ている)を作成し、それを変更することができると思います。 –

+0

これは私が「厳密にクラスに追加するのではなく、クラスがピクチャにないので」という意味です。むしろ、 '動的'によって参照される個々のオブジェクトは、それまでに存在しなかったプロパティへの代入を受け入れることができ、動的にプロパティを追加することによってこれを処理することができます。 –

6

クラスのすべてがメタデータに基づいているため、C#では許可されていません。 CLR(C#ではなく)は、runtime(1)でメタデータにフィールドを追加することを禁止しています。これは、C#がrunitmeでフィールドを追加できる唯一の方法です。

これは、本質的に具体的なメタデータクラスを持たないIronPythonなどの動的ランゲージとは異なります。実行時に変更することができるより動的な構造を持っています。 IronPythonは、実行時に簡単に変更できるハッシュテーブルにどの程度の量のメンバ(フィールドとメソッド)を保持していると思います。

C#3.0では、Reflection.Emitを使用することをお勧めします。しかし、これは全く新しいクラスを生成し、既存のクラスを変更します。

(1)これにはプロファイリングAPIやENCなどのAPIがありますが、機能を拡張するかどうかはわかりません。

1

他にも既に述べたように、これは不可能です。あなたの質問の理由は何ですか?

class My { 
    Dictionary<string, object> data; 
    public My() { data = new Dictionary<string, object>(); } 
} 

..しかし、それは本当にあなたが実際に達成したいのかによって異なります。あなたは、動的にクラスにいくつかの追加データを保存する必要がある場合は、おそらく辞書を使用することができますか?

+0

私の目的は、IExpandoインターフェイスを実装することです。私の最大の目的は、javascriptコードがActiveXオブジェクトに動的に「javascriptで」フィールドを追加できるようにすることです。たとえば、 var myobj = new ActiveXObject( 'server.object'); myobj.ArbitraryField = "何か"; 注意してくださいArbirtaryField does not exist –

1

IDictionaryとしてキャストして、C#4.0で簡単に行う方法については、this questionを参照してください。これにより、辞書に追加された値がオブジェクトのプロパティになります。私はanother answer of mineでこれが実証されていることを実証しています。

ただし、これはExpandoObjectのインスタンスまたはサブクラスDynamicObjectでのみ可能です。

IDynamicMetaObjectProviderが実装されている場合は、他のクラスで使用することもできますが、正常に動作するにはあまりにも多くの作業が必要です。

0

おそらく、デコレータパターンを使用できます。

オブジェクト指向プログラミングでは、デコレータパターンは、同じクラスの他のオブジェクトの動作に影響を与えることなく、静的または動的に個々のオブジェクトに動作を追加できるデザインパターンです。

http://www.dofactory.com/Patterns/PatternDecorator.aspx

[私はC#で動的プロパティを作成するにはどうすればよい?](の
関連する問題