Was sind die Unterschiede zwischen System.Dynamic.ExpandoObject
, System.Dynamic.DynamicObject
unddynamic
?
In welchen Situationen verwenden Sie diese Typen?
Was sind die Unterschiede zwischen System.Dynamic.ExpandoObject
, System.Dynamic.DynamicObject
unddynamic
?
In welchen Situationen verwenden Sie diese Typen?
Das dynamic
Schlüsselwort wird verwendet, um Variablen zu deklarieren, die spät gebunden werden sollen.
Wenn Sie eine späte Bindung für einen realen oder imaginären Typ verwenden möchten, verwenden Sie diedynamic
Schlüsselwort und der Compiler erledigt den Rest.
Wenn Sie das dynamic
Schlüsselwort verwenden, um mit einer normalen Instanz, dem DLR, zu interagieren spät gebundene Aufrufe der normalen Methoden der Instanz durch.
Die IDynamicMetaObjectProvider
Schnittstelle ermöglicht es einer Klasse, die Kontrolle über ihr spät gebundenes Verhalten zu übernehmen.
Wenn Sie das dynamic
Schlüsselwort für die Interaktion mit einer IDynamicMetaObjectProvider
Implementierung verwenden, ruft das DLR die IDynamicMetaObjectProvider
Methoden auf und das Objekt selbst entscheidet, was zu tun ist.
Die ExpandoObject
und DynamicObject
Klassen sind Implementierungen von IDynamicMetaObjectProvider
.
ExpandoObject
ist eine einfache Klasse, mit der Sie Mitglieder zu einer Instanz hinzufügen und sie als dynamic
Verbündeten verwenden können .
DynamicObject
ist eine erweiterte Implementierung, die vererbt werden kann, um auf einfache Weise ein benutzerdefiniertes Verhalten bereitzustellen.
Ich werde versuchen, eine klarere Antwort auf diese Frage zu geben, um klar zu erklären, was die Unterschiede zwischen dynamisch
ExpandoObject
und sindDynamicObject
.Sehr schnell
dynamic
ist ein Schlüsselwort. Es ist kein Typ an sich. Es ist ein Schlüsselwort, das den Compiler anweist, die statische Typprüfung zur Entwurfszeit zu ignorieren und stattdessen zur Laufzeit die späte Bindung zu verwenden. Wir werden alsodynamic
im Rest dieser Antwort nicht viel Zeit damit verbringen .ExpandoObject
undDynamicObject
sind in der Tat Typen. Auf der OBERFLÄCHE sehen sie einander sehr ähnlich. Beide Klassen implementierenIDynamicMetaObjectProvider
. Wenn Sie jedoch tiefer graben, werden Sie feststellen, dass sie sich überhaupt nicht ähneln.DynamicObject ist eine Teilimplementierung, die
IDynamicMetaObjectProvider
lediglich als Ausgangspunkt für Entwickler gedacht ist , um ihre eigenen benutzerdefinierten Typen zu implementieren, die den dynamischen Versand mit benutzerdefiniertem zugrunde liegenden Speicher- und Abrufverhalten unterstützen, damit der dynamische Versand funktioniert.Kurz gesagt, verwenden Sie DynamicObject, wenn Sie Ihre EIGENEN Typen erstellen möchten, die mit dem DLR verwendet werden können, und mit den von Ihnen gewünschten CUSTOM-Verhaltensweisen arbeiten möchten.
Beispiel: Stellen Sie sich vor, Sie möchten einen dynamischen Typ haben, der einen benutzerdefinierten Standard zurückgibt, wenn versucht wird, ein Mitglied abzurufen, das NICHT vorhanden ist (dh zur Laufzeit nicht hinzugefügt wurde). Und diese Standardeinstellung lautet: "Es tut mir leid, in diesem Glas befinden sich keine Cookies!". Wenn Sie ein dynamisches Objekt möchten, das sich so verhält, müssen Sie steuern, was passiert, wenn ein Feld nicht gefunden wird. ExpandoObject lässt Sie dies nicht zu. Sie müssen also Ihren eigenen Typ mit einem eindeutigen Verhalten für die dynamische Elementauflösung (Versand) erstellen und diesen anstelle des vorgefertigten verwenden
ExpandoObject
.Sie können einen Typ wie folgt erstellen: (Beachten Sie, dass der folgende Code nur zur Veranschaulichung dient und möglicherweise nicht ausgeführt wird. Um zu erfahren, wie Sie DynamicObject ordnungsgemäß verwenden, finden Sie an anderer Stelle viele Artikel und Tutorials.)
Jetzt können wir diese imaginäre Klasse, die wir gerade erstellt haben, als dynamischen Typ verwenden, der ein sehr benutzerdefiniertes Verhalten aufweist, wenn das Feld nicht vorhanden ist.
ExpandoObject
ist eine vollständige Implementierung vonIDynamicMetaObjectProvider
, bei der das .NET Framework-Team all diese Entscheidungen für Sie getroffen hat. Dies ist nützlich, wenn Sie kein benutzerdefiniertes Verhalten benötigen und ExpandoObject Ihrer Meinung nach gut genug für Sie funktioniert (in 90% der FälleExpandoObject
ist es gut genug). Sehen Sie sich zum Beispiel Folgendes an, und für ExpandoObject haben die Designer beschlossen, eine Ausnahme auszulösen, wenn das dynamische Element nicht vorhanden ist.Zusammenfassend
ExpandoObject
ist dies einfach eine vorgewählte Möglichkeit, DynamicObject um bestimmte dynamische Versandverhalten zu erweitern, die wahrscheinlich für Sie funktionieren werden , jedoch möglicherweise nicht von Ihren speziellen Anforderungen abhängen.Während
DyanmicObject
ist ein Helfer BaseType, der die Implementierung Ihrer eigenen Typen mit einzigartigen dynamischen Verhaltensweisen einfach und leicht macht.Ein nützliches Tutorial, auf dem ein Großteil der obigen Beispielquelle basiert.
quelle
DynamicObject
:TryGetMember
Wenn Sie beim Überschreiben false zurückgeben,RuntimeBinderException
wird beim Versuch, auf nicht vorhandene Eigenschaften zuzugreifen, a ausgelöst. Damit das Snippet tatsächlich funktioniert, sollten Sie zurückkehrentrue
.Gemäß der C # -Sprachenspezifikation
dynamic
handelt es sich um eine Typdeklaration. Dhdynamic x
bedeutet, dass die Variablex
den Typ hatdynamic
.DynamicObject
ist ein Typ, der die Implementierung erleichtertIDynamicMetaObjectProvider
und somit das spezifische Bindungsverhalten für den Typ überschreibt.ExpandoObject
ist ein Typ, der sich wie eine Eigenschaftstasche verhält. Das heißt, Sie können dynamischen Instanzen dieses Typs zur Laufzeit Eigenschaften, Methoden usw. hinzufügen.quelle
dynamic
ist kein tatsächlicher Typ ... es ist nur ein Hinweis, den Compiler anzuweisen, die späte Bindung für diese Variable zu verwenden.dynamic
Variablen werden tatsächlich wieobject
in MSILDas obige Beispiel von
DynamicObject
zeigt den Unterschied nicht klar, da es im Grunde die Funktionalität implementiert, die bereits von bereitgestellt wirdExpandoObject
.In den beiden unten genannten Links ist es sehr klar, dass es mit Hilfe von
DynamicObject
möglich ist, den tatsächlichen Typ beizubehalten / zu ändern (XElement
in dem in den folgenden Links verwendeten Beispiel) und die Eigenschaften und Methoden besser zu steuern.https://blogs.msdn.microsoft.com/csharpfaq/2009/09/30/dynamic-in-c-4-0-introducing-the-expandoobject/
https://blogs.msdn.microsoft.com/csharpfaq/2009/10/19/dynamic-in-c-4-0-creating-wrappers-with-dynamicobject/
quelle