質問

ExpandoObject クラス.NET 4に追加されると、実行時にオブジェクトにプロパティを任意に設定できます。

Dictionary<string, object> を使用するよりも、これに利点はありますか、または実際にハッシュテーブルですか?私が知る限り、これはハッシュテーブルに過ぎず、少し簡潔な構文でアクセスできます。

たとえば、これはなぜですか:

dynamic obj = new ExpandoObject();
obj.MyInt = 3;
obj.MyString = "Foo";
Console.WriteLine(obj.MyString);

以下よりも本当に優れている、または大幅に異なる:

var obj = new Dictionary<string, object>();
obj["MyInt"] = 3;
obj["MyString"] = "Foo";

Console.WriteLine(obj["MyString"]);

実行時に決定されるタイプを使用していることが明らかでないことを除いて、任意のディクショナリタイプを使用する代わりにExpandoObjectを使用することにより、本当のの利点が得られます。

役に立ちましたか?

解決

あなたが言及しているMSDNの記事を書いたので、私はこれに答えなければならないと思います。

最初に、私はこの質問を予想していたため、ExpandoObjectの実際の使用例を多かれ少なかれ示すブログ投稿を書いたのです。 C#4.0の動的:ExpandoObjectの紹介

まもなく、ExpandoObjectは複雑な階層オブジェクトの作成に役立ちます。たとえば、辞書内に辞書があるとします:

Dictionary<String, object> dict = new Dictionary<string, object>();
Dictionary<String, object> address = new Dictionary<string,object>();
dict["Address"] = address;
address["State"] = "WA";
Console.WriteLine(((Dictionary<string,object>)dict["Address"])["State"]);

より深いのは階層であり、ugいのはコードです。 ExpandoObjectを使用すると、エレガントで読みやすくなります。

dynamic expando = new ExpandoObject();
expando.Address = new ExpandoObject();
expando.Address.State = "WA";
Console.WriteLine(expando.Address.State);

第二に、すでに指摘したように、ExpandoObjectはINotifyPropertyChangedインターフェイスを実装し、ディクショナリよりもプロパティを詳細に制御できるようにします。

最後に、次のようにイベントをExpandoObjectに追加できます。

class Program
{
   static void Main(string[] args)
   {
       dynamic d = new ExpandoObject();

       // Initialize the event to null (meaning no handlers)
       d.MyEvent = null;

       // Add some handlers
       d.MyEvent += new EventHandler(OnMyEvent);
       d.MyEvent += new EventHandler(OnMyEvent2);

       // Fire the event
       EventHandler e = d.MyEvent;

       if (e != null)
       {
           e(d, new EventArgs());
       }

       // We could also fire it with...
       //      d.MyEvent(d, new EventArgs());

       // ...if we knew for sure that the event is non-null.
   }

   static void OnMyEvent(object sender, EventArgs e)
   {
       Console.WriteLine("OnMyEvent fired by: {0}", sender);
   }

   static void OnMyEvent2(object sender, EventArgs e)
   {
       Console.WriteLine("OnMyEvent2 fired by: {0}", sender);
   }
}

他のヒント

1つの利点は、シナリオをバインドすることです。データグリッドとプロパティグリッドは、TypeDescriptorシステムを介して動的プロパティを取得します。さらに、WPFデータバインディングは動的プロパティを理解するため、WPFコントロールは辞書よりもExpandoObjectに簡単にバインドできます。

ディクショナリエントリではなくDLRプロパティを想定している動的言語との相互運用性も、いくつかのシナリオで考慮事項になる場合があります。

私にとっての本当の利点は、XAMLからの完全に楽なデータバインディングです:

public dynamic SomeData { get; set; }

...

SomeData.WhatEver = "Yo Man!";

...

 <TextBlock Text="{Binding SomeData.WhatEver}" />

DLRに基づいて構築された他の言語との相互運用が、私が考えることができる一番の理由です。 Dictionary<string, object>ではないため、IDynamicMetaObjectProviderを渡すことはできません。もう1つの利点は、INotifyPropertyChangedを実装することです。つまり、WPFのデータバインディングの世界では、Dictionary<K,V>が提供できる以上の利点があります。

それは、プログラマーの利便性に関するものです。このオブジェクトを使って、すばやく汚いプログラムを書くことを想像できます。

もう<!> quot; faking <!> quot;でなくなるので、構文上の利点があると思います。辞書を使用して動的に追加されたプロパティ。

それで、私が思うに動的言語との相互運用。

ExpandoObjectの使用に関する優れた MSDNの記事の例着信構造化データ(つまり、XML、Json)の動的なアドホックタイプを作成します。

ExpandoObject の動的プロパティにデリゲートを割り当てることもできます。

dynamic person = new ExpandoObject();
person.FirstName = "Dino";
person.LastName = "Esposito";

person.GetFullName = (Func<String>)(() => { 
  return String.Format("{0}, {1}", 
    person.LastName, person.FirstName); 
});

var name = person.GetFullName();
Console.WriteLine(name);

したがって、実行時に動的オブジェクトにいくつかのロジックを挿入できます。 したがって、ラムダ式、クロージャ、動的キーワード、および DynamicObjectクラス、関数プログラミングのいくつかの要素をC#コードに導入できます。これは、JavaScriptやPHPなどの動的言語から知っています。

これが便利な場合があります。たとえば、モジュール化されたシェルに使用します。各モジュールは、その設定にデータバインドされた独自の構成ダイアログを定義します。 DatacontextとしてExpandoObjectを提供し、構成ストレージに値を保存します。このように、構成ダイアログライターは値にバインドするだけで、自動的に作成および保存されます。 (そしてもちろんこれらの設定を使用するためにモジュールに提供されます)

辞書よりも簡単に使用できます。しかし、誰もが内部的には単なる辞書であることに注意する必要があります。

LINQは単なる構文糖のようですが、時には物事が簡単になります。

あなたの質問に直接答える:書きやすく、読みやすいです。しかし、技術的には本質的にはDictionary<string,object>です(値をリストするためにキャストすることもできます)。

var obj = new Dictionary<string, object>;
...
Console.WriteLine(obj["MyString"]);

すべてがToString()を持っているためにのみ機能すると思います。そうでなければ、それがあった型を知り、その型に「オブジェクト」をキャストする必要があります。


これらのいくつかは他のものよりも頻繁に有用であり、徹底的にしようとしています。

  1. コレクションにアクセスする方がはるかに自然かもしれません。この場合、より直接的なドット表記を使用して、事実上<!> quot; dictionary <!> quot;です。

  2. これは本当に素晴らしいTupleとして使用できるようです。まだメンバー<!> quot; Item1 <!> quot;、<!> quot; Item2 <!> quot;を呼び出すことができます。など...しかし、今では必要はありません。タプルとは異なり、可変です。これには、インテリセンスのサポートがないという大きな欠点があります。

  3. <!> quot;文字列としてのメンバー名<!> quot;は不快かもしれません。辞書の感触と同様に、<!> quot;文字列を実行する<! > quot;そして、命名規則がコード化され、コードがメンバーの使用方法を理解しようとしているときに形態素と音節を扱うことにつながる可能性があります:-P

  4. ExpandoObject自体に値を割り当てることはできますか? dynamic / dynamic []と比較して対比し、ニーズに最適な方を使用してください。

  5. foreachループでdynamic / dynamic []が機能するとは思わないので、varを使用する必要がありますが、ExpandoObjectを使用することもできます。

  6. クラスのデータメンバとしてdynamicを使用することはできません。おそらく、少なくともキーワードのようなものだからです。ExpandoObjectで使用できればと思います。

  7. <!> quot; is <!> quot; ExpandoObjectは、多くの動的なものが使用されている型に基づいて区別するコードを使用して、非常に一般的なものを区別するのに役立ちます。


一度に複数のレベルをドリルダウンできると便利です。

var e = new ExpandoObject();
e.position.x = 5;
etc...

これは最良の例ではありませんが、自分のプロジェクトで適切なエレガントな使い方を想像してください。

これらの一部をコードでビルドして、その結果をインテリセンスにプッシュできないのは残念です。しかし、これがどのように機能するかはわかりません。

メンバーだけでなく値も持つことができれば、親切にしてください。

var fifteen = new ExpandoObject();
fifteen = 15;
fifteen.tens = 1;
fifteen.units = 5;
fifteen.ToString() = "fifteen";
etc...

valueTuplesの後、ExpandoObjectクラスの使用は何ですか? ExpandoObjectを使用したこの6行のコード:

dynamic T = new ExpandoObject();
T.x = 1;
T.y = 2;
T.z = new ExpandoObject();
T.z.a = 3;
T.b= 4;

タプルを使用して1行で記述できます:

var T = (x: 1, y: 2, z: (a: 3, b: 4));

タプル構文に加えて、強力な型推論とintlisenseサポートがあります

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top