wake-up-neo.com

Was sind die wahren Vorteile von ExpandoObject?

Mit der in .NET 4 hinzugefügten Klasse ExpandoObject können Sie Eigenschaften für ein Objekt zur Laufzeit beliebig festlegen.

Gibt es irgendwelche Vorteile gegenüber der Verwendung von Dictionary<string, object> oder wirklich sogar ein Hashtable ? Soweit ich das beurteilen kann, handelt es sich hierbei nur um eine Hash-Tabelle, auf die Sie mit etwas prägnanterer Syntax zugreifen können.

Zum Beispiel, warum ist das:

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

Wirklich besser oder wesentlich anders als:

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

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

Welche echten Vorteile ergeben sich durch die Verwendung von ExpandoObject anstelle der Verwendung eines beliebigen Wörterbuchtyps zur Laufzeit ermittelt werden.

563
Reed Copsey

Da ich den MSDN-Artikel geschrieben habe, auf den Sie sich beziehen, muss ich diesen wohl beantworten.

Zuerst habe ich diese Frage vorweggenommen und deshalb habe ich einen Blog-Beitrag geschrieben, der einen mehr oder weniger realen Anwendungsfall für ExpandoObject zeigt: Dynamisch in C # 4.0: Einführung in ExpandoObject .

Mit ExpandoObject können Sie in Kürze komplexe hierarchische Objekte erstellen. Angenommen, Sie haben ein Wörterbuch in einem Wörterbuch:

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

Je tiefer die Hierarchie ist, desto hässlicher ist der Code. Mit ExpandoObject bleibt es elegant und lesbar.

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

Zweitens implementiert ExpandoObject, wie bereits erwähnt, die INotifyPropertyChanged-Schnittstelle, mit der Sie die Eigenschaften besser steuern können als mit einem Wörterbuch.

Schließlich können Sie ExpandoObject Ereignisse wie hier hinzufügen:

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

Ein Vorteil ist das Binden von Szenarien. Datenraster und Eigenschaftsraster erfassen die dynamischen Eigenschaften über das TypeDescriptor-System. Darüber hinaus werden bei der WPF-Datenbindung dynamische Eigenschaften berücksichtigt, sodass WPF-Steuerelemente leichter an ein ExpandoObject gebunden werden können als an ein Wörterbuch.

Die Interoperabilität mit dynamischen Sprachen, die DLR-Eigenschaften anstelle von Wörterbucheinträgen erwarten, kann in einigen Szenarien ebenfalls eine Rolle spielen.

74
itowlson

Der eigentliche Vorteil für mich ist die völlig mühelose Datenbindung von XAML:

public dynamic SomeData { get; set; }

...

SomeData.WhatEver = "Yo Man!";

...

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

Interop mit anderen Sprachen, die auf DLR basieren, ist der Hauptgrund, an den ich denken kann. Sie können ihnen keinen Dictionary<string, object> Übergeben, da es sich nicht um einen IDynamicMetaObjectProvider handelt. Ein weiterer zusätzlicher Vorteil ist die Implementierung von INotifyPropertyChanged, was bedeutet, dass es in der Datenbindungswelt von WPF auch zusätzliche Vorteile bietet, die über das hinausgehen, was Dictionary<K,V> Ihnen bieten kann.

27
Drew Marsh

Es geht nur um die Bequemlichkeit des Programmierers. Ich kann mir vorstellen, mit diesem Objekt schnelle und schmutzige Programme zu schreiben.

19
ChaosPandion

Ich denke, es wird einen syntaktischen Vorteil haben, da Sie nicht länger dynamisch hinzugefügte Eigenschaften "vortäuschen", indem Sie ein Wörterbuch verwenden.

Das und Interop mit dynamischen Sprachen würde ich denken.

14
gn22

Es ist ein Beispiel von great MSDN-Artikel über die Verwendung von ExpandoObject zum Erstellen dynamischer Ad-hoc-Typen für eingehende strukturierte Daten (z. B. XML, Json) ).

Wir können Delegate auch der dynamischen Eigenschaft von ExpandoObject zuweisen:

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

Auf diese Weise können wir zur Laufzeit Logik in ein dynamisches Objekt einfügen. Daher können wir zusammen mit Lambda-Ausdrücken, Closures, dynamischem Schlüsselwort und DynamicObject-Klasse einige Elemente der funktionalen Programmierung in unseren C # -Code einfügen, den wir aus dynamischen Sprachen wie JavaScript oder PHP kennen.

11
sgnsajgon

In einigen Fällen ist dies praktisch. Ich werde es zum Beispiel für eine Modularisierte Shell verwenden. Jedes Modul definiert seinen eigenen Konfigurationsdialog, der an seine Einstellungen gebunden ist. Ich versorge es mit einem ExpandoObject als Datenkontext und speichere die Werte in meinem Konfigurationsspeicher. Auf diese Weise muss der Konfigurationsdialog-Writer nur an einen Wert binden, und er wird automatisch erstellt und gespeichert. (Und natürlich dem Modul zur Verfügung gestellt, um diese Einstellungen zu verwenden)

Es ist einfach einfacher zu benutzen als ein Wörterbuch. Aber jeder sollte sich darüber im Klaren sein, dass es sich intern nur um ein Wörterbuch handelt.

Es ist wie bei LINQ nur syntaktischer Zucker, aber es macht die Dinge manchmal einfacher.

Um Ihre Frage direkt zu beantworten: Es ist einfacher zu schreiben und leichter zu lesen. Aber technisch ist es im Wesentlichen ein Dictionary<string,object> (Sie können es sogar in eins umwandeln, um die Werte aufzulisten).

4
n1LWeb