Frage

Die ExpandoObject Klasse hinzugefügt zu .NET 4 ermöglicht es Ihnen, Eigenschaften auf ein Objekt zur Laufzeit willkürlich festgelegt.

Gibt es irgendwelche Vorteile dieses über mit einem Dictionary<string, object> oder wirklich auch ein Hashtable ? Soweit ich sagen kann, ist dies nichts anderes als eine Hash-Tabelle, die Sie mit etwas prägnanten Syntax zugreifen können.

Zum Beispiel, warum ist dies:

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

Was real Vorteile gewonnen werden durch ExpandoObject anstelle von nur einen beliebigen Wörterbuchtyp verwendet wird, anders als nicht offensichtlich sein, dass Sie eine Art verwenden, die zur Laufzeit bestimmt los werden.

War es hilfreich?

Lösung

Da ich im MSDN-Artikel schrieb, Sie beziehen sich auf, ich denke, ich habe diese zu beantworten.

Zuerst habe ich diese Frage erwartet und deshalb habe ich einen Blog-Post schrieb, die eine mehr oder weniger zeigt realen Anwendungsfall für ExpandoObject: Dynamische in C # 4.0: Einführung in das ExpandoObject .

In Kürze können ExpandoObject helfen Ihnen, komplexe hierarchische Objekte zu erstellen. Zum Beispiel vorstellen, dass Sie ein Wörterbuch in einem Wörterbuch haben:

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 ist die Hierarchie, desto hässlicher wird der Code. Mit ExpandoObject bleibt es elegant und gut lesbar.

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

Zweitens, wie es wurde bereits darauf hingewiesen, implementiert ExpandoObject INotifyPropertyChanged-Schnittstelle, die Ihnen mehr Kontrolle über Eigenschaften als ein Wörterbuch gibt.

Schließlich können Sie Ereignisse hinzufügen, wie hier 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);
   }
}

Andere Tipps

Ein Vorteil ist für Szenarien verbindlich. Datennetze und Eigentum Grids werden die dynamischen Eigenschaften über das TypeDescriptor System abholen. Darüber hinaus Bindung WPF Daten dynamische Eigenschaften verstehen, so steuert WPF zu einem ExpandoObject leichter als ein Wörterbuch binden kann.

Die Interoperabilität mit dynamischen Sprachen, die DLR-Eigenschaften erwartet wird, eher als Wörterbucheinträge, auch eine Überlegung in einigen Szenarien sein kann.

Der eigentliche Vorteil für mich ist die völlig mühelos Daten von XAML-Bindung:

public dynamic SomeData { get; set; }

...

SomeData.WhatEver = "Yo Man!";

...

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

Interop mit anderen auf der DLR gegründet Sprachen ist # 1 Grund, warum ich mir vorstellen kann. Sie können sie nicht ein Dictionary<string, object> passieren, da es nicht ein IDynamicMetaObjectProvider ist. Ein weiterer Vorteil ist, dass es INotifyPropertyChanged implementiert, die in der Welt der Datenbindung WPF bedeutet, es hat auch zusätzliche Vorteile hinaus, was Dictionary<K,V> können Sie zur Verfügung stellen.

Es ist alles über Programmierer Komfort. Ich kann mit diesem Objekt zu schreiben schnell und schmutzig Programme vorstellen.

ich denke, es wird eine syntaktische Nutzen hat, da Sie nicht mehr durch die Verwendung eines Wörterbuch dynamisch hinzugefügt Eigenschaften „fälschen“ werden.

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

Es ist beispielsweise von großen MSDN-Artikel über die Verwendung von ExpandoObject zur Erstellung von dynamischen ad-hoc-Typen für eingehende strukturierte Daten (zB XML, JSON).

Wir können auch zuweisen Delegierter ExpandoObject 's dynamische Eigenschaft:

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

So erlaubt es uns, eine gewisse Logik in dynamisches Objekt zur Laufzeit zu injizieren. Daher zusammen mit Lambda-Ausdrücke, Verschlüssen, dynamischen Keyword und Dynamic Klasse können wir einige Elemente der funktionalen Programmierung in unseren C # -Code einführen, die wir von dynamischen Sprachen wie wie JavaScript oder PHP kennen.

Es gibt einige Fälle, in denen dies praktisch ist. Ich werde es für eine modularisierte Shell zum Beispiel verwenden. Jedes Modul definiert seine eigene Konfigurationsdialog databinded es Einstellungen ist. Ich stelle es mit einem ExpandoObject wie es ist und Datacontext die Werte in meiner Konfiguration Speicher speichern. Auf diese Weise der Konfigurationsdialog Verfasser hat nur auf einen Wert binden und es wird automatisch erstellt und gespeichert. (Und für die Verwendung dieser Einstellungen natürlich an das Modul zur Verfügung gestellt)

Es einfach leichter als ein Wörterbuch zu verwenden. Aber jeder sollte sich bewusst sein, dass es intern ist nur ein Wörterbuch.

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

So 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 auch gegossen in einer der Werte zur Liste).

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

Ich denke, das funktioniert nur, weil alles, was eine ToString (), sonst würden Sie den Typen wissen müssen, dass es war, und warf das ‚Objekt‘ auf diese Art.


Einige davon sind nützlich, häufiger als andere, ich versuche, gründlich zu sein.

  1. Es kann viel natürlicher sein, eine Sammlung zugreifen zu können, was in diesem Fall ist effektiv ein „Wörterbuch“, die mehr direkte Punktnotation verwendet wird.

  2. Es scheint, als ob dies als eine wirklich schöne Tuple verwendet werden könnte. Sie können noch Ihre Mitglieder „Element1“, „Element2“ usw. nennen ... aber jetzt haben Sie nicht, es ist auch wandelbar, im Gegensatz zu einem Tuple. Dies hat den großen Nachteil der fehlenden IntelliSense-Unterstützung hat.

  3. Sie können mit „Mitgliedsnamen als Strings“, unbequem sein, wie das Gefühl mit dem Wörterbuch ist, fühlt man kann es auch wie „Ausführen Strings“ ist, und es kann zu Namenskonventionen führen in immer codiert, und Umgang mit mit Morphemen und Silben zu arbeiten, wenn Code verstehen versucht, wie die Mitglieder verwenden :-P

  4. Können Sie Wert auf ein ExpandoObject selbst zuweisen oder ihre Mitglieder nur? Vergleichen und mit dynamischem / dynamic [], je nachdem, was dem Einsatz am besten Ihre Bedürfnisse.

  5. Ich glaube nicht dynamisch / dynamische [] Arbeiten in einer foreach-Schleife, Sie haben var zu verwenden, aber möglicherweise können Sie ExpandoObject verwenden.

  6. Sie können als Datenelement in einer Klasse nicht dynamisch verwenden, vielleicht, weil es wie ein Schlüsselwort zumindest eine Art ist, hoffentlich können Sie mit ExpandoObject.

  7. Ich erwarte, dass es „ist“ ein ExpandoObject, könnte nützlich sein, sehr allgemeine Dinge auseinander zu beschriften, mit Code, der auf Typen auf Basis differenziert, wo es viele dynamischen Sachen verwendet wird.


schön, wenn Sie mehrere Ebenen Drilldown könnte.

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

Das ist nicht das bestmögliche Beispiel vorstellen, elegante Anwendungen als angemessen in Ihren eigenen Projekten.

Es ist eine Schande Sie nicht Code zu bauen einige davon und drücken Sie die Ergebnisse intellisense haben. Ich bin mir nicht sicher, wie dies obwohl funktionieren würde.

Seien Sie nett, wenn sie einen Wert sowie Mitglieder haben könnte.

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

Nach valueTuples, was ist der Einsatz von ExpandoObject Klasse? dieser 6 Zeilen Code mit ExpandoObject:

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

kann in einer Linie mit Tupel geschrieben werden:

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

neben mit Tupel Syntax Sie haben eine starke Typinferenz und intlisense Unterstützung

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top