640 Stimmen

Was sind die wahren Vorteile von ExpandoObject?

Le site ExpandoObject Klasse, die zu .NET 4 hinzugefügt wurde, ermöglicht es Ihnen, einem Objekt zur Laufzeit beliebige Eigenschaften zuzuweisen.

Gibt es irgendwelche Vorteile gegenüber der Verwendung eines Dictionary<string, object> oder sogar ein Hashtabelle ? Soweit ich weiß, ist dies nichts anderes als eine Hashtabelle, auf die man mit einer etwas prägnanteren Syntax zugreifen kann.

Warum ist das zum Beispiel so?

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 durch die Verwendung von ExpandoObject anstelle eines beliebigen Wörterbuchtyps, außer dass es nicht offensichtlich ist, dass Sie einen Typ verwenden, der zur Laufzeit bestimmt wird.

15voto

gn22 Punkte 2076

Ich denke, es wird einen syntaktischen Vorteil haben, da man nicht mehr dynamisch hinzugefügte Eigenschaften durch die Verwendung eines Wörterbuchs "vortäuschen" muss.

Das und die Interoperabilität mit dynamischen Sprachen, würde ich meinen.

14voto

sgnsajgon Punkte 617

Es ist ein Beispiel von großer MSDN-Artikel über die Verwendung ExpandoObject zur Erstellung dynamischer Ad-hoc-Typen für eingehende strukturierte Daten (z. B. XML, Json).

Wir können den Delegierten auch zuweisen ExpandoObject 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 können wir zur Laufzeit eine gewisse Logik in dynamische Objekte einbauen. Zusammen mit Lambda-Ausdrücken, Closures, dynamischen Schlüsselwörtern und DynamicObject-Klasse können wir einige Elemente der funktionalen Programmierung in unseren C#-Code einbringen, die wir aus dynamischen Sprachen wie JavaScript oder PHP kennen.

4voto

n1LWeb Punkte 41

Es gibt einige Fälle, in denen dies praktisch ist. 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 ihn mit einem ExpandoObject als Datentext und speichere die Werte in meinem Konfigurationsspeicher. Auf diese Weise muss der Autor des Konfigurationsdialogs nur an einen Wert binden und dieser 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 intern nur ein Wörterbuch ist.

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

Um Ihre Frage also direkt zu beantworten: Es ist leichter zu schreiben und leichter zu lesen. Aber technisch gesehen ist es im Wesentlichen ein Dictionary<string,object> (Sie können sie sogar in eine Liste der Werte umwandeln).

-1voto

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

Ich denke, das funktioniert nur, weil alles eine ToString() hat, sonst müsste man den Typ kennen, der es war, und das "Objekt" auf diesen Typ übertragen.


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

  1. Es ist vielleicht viel natürlicher, auf eine Sammlung, in diesem Fall ein "Wörterbuch", mit der direkteren Punktnotation zuzugreifen.

  2. Es scheint, als ob dies als ein wirklich schönes Tupel verwendet werden könnte. Sie können immer noch Ihre Mitglieder "Item1", "Item2" usw. nennen... aber jetzt müssen Sie nicht, es ist auch veränderbar, im Gegensatz zu einem Tuple. Dies hat den großen Nachteil der Mangel an Intellisense-Unterstützung.

  3. Sie mögen sich mit "Mitgliedsnamen als Zeichenketten" unwohl fühlen, so wie es sich mit dem Wörterbuch anfühlt, Sie mögen es als zu ähnlich empfinden wie das "Ausführen von Zeichenketten", und es kann dazu führen, dass Namenskonventionen einkodiert werden und man mit Morphemen und Silben arbeiten muss, wenn der Code versucht zu verstehen, wie man die Mitglieder verwendet :-P

  4. Kann man einem ExpandoObject selbst einen Wert zuweisen oder nur seinen Membern? Vergleichen und kontrastieren Sie mit dynamic/dynamic[], verwenden Sie das, was Ihren Bedürfnissen am besten entspricht.

  5. Ich glaube nicht, dass dynamic/dynamic[] in einer foreach-Schleife funktioniert, Sie müssen var verwenden, aber möglicherweise können Sie ExpandoObject verwenden.

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

  7. Ich nehme an, es "ist" ein ExpandoObject, könnte nützlich sein, um sehr generische Dinge auseinander zu kennzeichnen, mit Code, der auf der Grundlage von Typen unterscheidet, wo es viel dynamisches Zeug verwendet wird.


Es wäre schön, wenn Sie mehrere Ebenen auf einmal aufschlüsseln könnten.

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

Das ist nicht das bestmögliche Beispiel, stellen Sie sich elegante Verwendungen in Ihren eigenen Projekten vor.

Es ist eine Schande, dass man einige davon nicht mit Code erstellen und die Ergebnisse an Intellisense übergeben kann. Ich bin mir aber nicht sicher, wie das funktionieren würde.

Es wäre schön, wenn sie neben den Mitgliedern auch einen Wert haben könnten.

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

-3voto

Eng. M.Hamdy Punkte 240

Wozu dient nach valueTuples die Klasse ExpandoObject? diese 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 Zeile mit Tupeln geschrieben werden:

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

neben der Tupel-Syntax gibt es eine starke Typinferenz und Intlisense-Unterstützung

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X