1. ホーム
  2. c#

[解決済み】ExpandoObjectの本当のメリットは何ですか?

2022-03-23 12:55:46

質問

その ExpandoObject クラスは、実行時にオブジェクトに任意にプロパティを設定することができます。

を使用した場合と比較して、何か利点があるのでしょうか? Dictionary<string, object> あるいは ハッシュテーブル ? 私の知る限り、これはハッシュテーブルに過ぎず、もう少し簡潔な構文でアクセスすることができます。

例えば、なぜ、これなのか。

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

Really better, or substantially different, than:

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"]);

階層が深ければ深いほど、コードは醜くなる。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;

       e?.Invoke(d, new EventArgs());
   }

   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);
   }
}

また、イベント引数をダイナミックに受け取ることを妨げるものは何もないことを覚えておいてください。言い換えれば EventHandler を使用することができます。 EventHandler<dynamic> とすると、ハンドラの第2引数が dynamic .