8

メンバーを動的オブジェクトに動的に追加する方法を探しています。OK、少し説明が必要だと思います...

あなたがそれをするとき:

dynamic foo = new ExpandoObject();
foo.Bar = 42;

プロパティはBar実行時に動的に追加されます。しかし、コードは引き続き Bar を「静的に」参照します (「Bar」という名前はハードコードされています)... コンパイル時に名前を知らずに実行時にプロパティを追加したい場合はどうすればよいでしょうか?

クラスのメソッドを使用して、カスタムの動的オブジェクトでこれを行う方法を知っていますが (実際には数か月前にブログを書きました)、動的オブジェクトでどのように行うことができますか?DynamicObject

おそらくIDynamicMetaObjectProviderインターフェースを使用できますが、使用方法がわかりません。たとえば、どの引数をGetMetaObjectメソッドに渡す必要がありますか? (それは を期待しますExpression)

ところで、動的オブジェクトに対してどのようにリフレクションを実行しますか? 「通常の」リフレクションでTypeDescriptor、動的メンバーを表示しない...

どんな洞察もいただければ幸いです!

4

4 に答える 4

9

必要なものは、Python の getattr/setattr 関数に似ています。C# または VB.NET でこれを行う同等の方法は組み込まれていません。DLR の外側の層 (Microsoft.Scripting.dll に IronPython と IronRuby が付属) には、GetMember/SetMember メソッドを持つ ObjectOperations API を含む一連のホスティング API が含まれています。それらを使用することもできますが、DLR と DLR ベースの言語の追加の依存関係が必要になります。

おそらく最も簡単な方法は、既存の C# バインダーの 1 つを使用して CallSite を作成することです。このコードは、ildasm または Reflector で "foo.Bar = 42" の結果を見ることで取得できます。しかし、これの簡単な例は次のようになります。

object x = new ExpandoObject();
CallSite<Func<CallSite, object, object, object>> site = CallSite<Func<CallSite, object, object, object>>.Create(
            Binder.SetMember(
                Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.None,
                "Foo",
                null,
                new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }
            )
        );
site.Target(site, x, 42);
Console.WriteLine(((dynamic)x).Foo);
于 2010-01-17T09:47:14.810 に答える
5

オープンソースフレームワークDynamiteyがこれを行います( nuget経由で利用可能)。@Dino-Viehlandが使用したコールサイトとバインダーコードをキャッシュしながらカプセル化します。

Dynamic.InvokeSet(foo,"Bar",42);

また、他の多くの種類のc#バインダーを呼び出すこともできます。

于 2011-07-06T19:49:31.020 に答える
5

ExpandoObjectは、明示的ではありますが、IDictionary <string、object>を実装します。これが意味するのは、ExpandoObjectをIDictionary <string、object>にキャストして、辞書を操作するだけでよいということです。

dynamic foo = new ExpandoObject();
foo.Bar = 42;
food = (IDictionary<string,object>)foo;
food["Baz"] = 54
于 2011-08-12T22:24:08.157 に答える
1

これはかなり古い投稿であることは承知していますが、独自の型を作成して実行時にプロパティを追加する方法について、Miron Abramson のソリューションを紹介したいと思います。

于 2012-03-28T22:38:25.070 に答える