Frage

Was sind die Unterschiede zwischen System.Dynamic.ExpandoObject, System.Dynamic.DynamicObject und dynamic?

In welchen Situationen Sie diese Art verwenden?

War es hilfreich?

Lösung

Das dynamic Schlüsselwort wird declare Variablen verwendet, die spät gebundene werden sollte.
Wenn Sie die späte Bindung, für einen wirklichen oder eingebildeten Typen verwenden mögen, verwenden Sie das Schlüsselwort dynamic und der Compiler erledigt den Rest.

Wenn Sie das dynamic Schlüsselwort interact mit einer normalen Instanz verwenden, die DLR führt spät gebundene Aufrufe an die Instanz des normalen Methoden.

Die IDynamicMetaObjectProvider Schnittstelle ermöglicht eine Klasse zu nehmen Kontrolle seiner spät gebundenen Verhalten.
Wenn Sie das dynamic Schlüsselwort mit einer IDynamicMetaObjectProvider Implementierung zu interagieren, die DLR ruft die IDynamicMetaObjectProvider Methoden und das Objekt selbst entscheidet, was zu tun ist.

Die ExpandoObject und DynamicObject Klassen sind Implementierungen von IDynamicMetaObjectProvider.

ExpandoObject ist eine einfache Klasse, die Sie Mitglieder zu einer Instanz hinzufügen können und nutzen sie dynamically.
DynamicObject ist eine erweiterte Implementierung, die leicht vererbt werden kann, um kundenspezifische Verhalten liefern.

Andere Tipps

Ich werde versuchen, eine klarere Antwort auf diese Frage zu finden, klar zu erklären, was die Unterschiede sind zwischen dynamischen, ExpandoObject und DynamicObject.

Sehr schnell ist dynamic ein Schlüsselwort. Es ist nicht eine Art pro-se. Es ist ein Schlüsselwort, das den Compiler sagt statische Typprüfung zur Entwurfszeit zu ignorieren und stattdessen späte Bindung zur Laufzeit zu nutzen. So werden wir nicht viel Zeit auf dynamic in dem Rest dieser Antwort verbringen.

ExpandoObject und DynamicObject sind in der Tat Arten. Auf der Oberfläche, sie sehen sich sehr ähnlich. Beiden Klassen implementieren IDynamicMetaObjectProvider. Allerdings tiefer graben und Sie werden alles, was sie sind nicht ähnlich zu finden.

Dynamic ist eine teilweise Umsetzung der IDynamicMetaObjectProvider rein sollte ein Ausgangspunkt sein für Entwickler ihre eigenen Typen Versand mit benutzerdefinierten zugrunde liegenden Lager- und Bereitstellungsverhalten Unterstützung dynamischer zu implementieren dynamischer Dispatch Arbeit zu machen.

  1. Dynamic kann nicht direkt aufgebaut werden.
  2. Sie MÜSSEN Dynamic erweitern es als Entwickler Ihnen jede Verwendung zu haben.
  3. Wenn Sie Dynamic erweitern Sie sind nun in der Lage CUSTOM Verhalten bieten darüber, wie Sie dynamischen Dispatch zu lösen, um Daten intern in Ihrer zugrunde liegenden Datendarstellung zur Laufzeit gespeichert werden sollen.
  4. ExpandoObject speichert Daten in einem Wörterbuch zugrunde liegen, etc. Wenn Sie Dynamic implementieren, können Sie Daten speichern, wo und wie Sie mögen. (Zum Beispiel, wie Sie die Daten beim Versand erhalten und eingestellt ist ganz bei Ihnen).

Kurz gesagt, die Verwendung, wenn Dynamic Sie Ihre eigene Typen erstellen, die mit dem DLR und der Arbeit verwendet werden kann, mit dem, was CUSTOM Verhaltensweisen, die Sie möchten.

Beispiel: Stellen Sie sich vor, dass Sie mögen, dass eine dynamische Art haben, dass die Renditen ein benutzerdefinierter Standard, wenn ein get auf einem Mitglied versucht wird, die nicht existiert (d wurde zur Laufzeit nicht hinzugefügt). Und das Standard wird sagen: „Es tut mir leid, es gibt keine Cookies in diesem Glas!“. Wenn Sie ein dynamisches Objekt möchten, dass verhält sich wie diese, müssen Sie kontrollieren, was passiert, wenn ein Feld nicht gefunden wird. ExpandoObject lassen Sie nicht tun. So müssen Sie Ihre eigene Art mit einzigartigen dynamischen Mitglied Auflösung (Versand) Verhalten und die Verwendung schaffen, dass anstelle des Fertig- ExpandoObject.

Sie können eine Art erstellen wie folgt: (.. Beachten Sie die folgenden Code nur zur Veranschaulichung und kann nicht laufen zu erfahren, wie Dynamic richtig zu nutzen, gibt es viele Artikel und Tutorials an anderer Stelle)

public class MyNoCookiesInTheJarDynamicObject : DynamicObject
{
    Dictionary<string, object> properties = new Dictionary<string, object>();

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if (properties.ContainsKey(binder.Name))
        {
            result = properties[binder.Name];
            return true;
        }
        else
        {
            result = "I'm sorry, there are no cookies in this jar!"; //<-- THIS IS OUR 
            CUSTOM "NO COOKIES IN THE JAR" RESPONSE FROM OUR DYNAMIC TYPE WHEN AN UNKNOWN FIELD IS ACCESSED
            return false;
        }
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        properties[binder.Name] = value;
        return true;
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        dynamic method = properties[binder.Name];
        result = method(args[0].ToString(), args[1].ToString());
        return true;
    }
}

Nun könnten wir diese imaginäre Klasse verwenden wir nur als dynamischen Typ geschaffen, die ein sehr individuelles Verhalten hat, wenn das Feld nicht existiert.

dynamic d = new MyNoCookiesInTheJarDynamicObject();
var s = d.FieldThatDoesntExist;

//in our contrived example, the below should evaluate to true
Assert.IsTrue(s == "I'm sorry, there are no cookies in this jar!")

ExpandoObject ist eine vollständige Umsetzung der IDynamicMetaObjectProvider, wo das .NET Framework-Team alle diese Entscheidungen für Sie gemacht hat. Dies ist nützlich, wenn Sie keine benutzerdefinierten Verhalten benötigen, und Sie glauben, dass ExpandoObject gut genug für Sie funktioniert (90% der Zeit, ist ExpandoObject gut genug). So zum Beispiel finden Sie in den folgenden, und dass für ExpandoObject die Designer wählten eine Ausnahme ausgelöst, wenn das dynamische Element existiert nicht.

dynamic d = new ExpandoObject();

/*
The ExpandoObject designers chose that this operation should result in an 
Exception. They did not have to make that choice, null could 
have been returned, for example; or the designers could've returned a "sorry no cookies in the jar" response like in our custom class. However, if you choose to use 
ExpandoObject, you have chosen to go with their particular implementation 
of DynamicObject behavior.
*/

try {
var s = d.FieldThatDoesntExist;
}
catch(RuntimeBinderException) { ... }

Um es zusammenzufassen, ExpandoObject ist einfach eine vorausgewählte Weise Dynamic mit bestimmten dynamischen Dispatch Verhaltensweisen zu erweitern, die wahrscheinlich für Sie arbeiten , kann aber nicht abhängig von Ihren speziellen Bedürfnissen.

Die DyanmicObject ist ein Helfer Basetype das macht Ihren eigenen Typen mit einzigartigen dynamischen Verhalten einfache Implementierung und einfach.

Ein nützliches Tutorial, auf dem ein großer Teil der Beispielquelle oben basiert.

Nach der Sprache C # Spezifikation dynamic ist eine Typdeklaration. D. h dynamic x bedeutet die Variable x den Typ dynamic hat.

DynamicObject ist eine Art, die es einfach macht IDynamicMetaObjectProvider zu implementieren und somit spezifische außer Kraft setzt Verhalten für den Typen zu binden.

ExpandoObject ist ein Typ, wie eine Eigenschaft Tasche wirkt. D. h Sie können Eigenschaften, Methoden hinzufügen und so weiter, um dynamische Instanzen dieses Typs zur Laufzeit.

Das obige Beispiel von DynamicObject nicht dem Unterschied deutlich macht sagen, weil es die Funktionalität im Grunde ist die Umsetzung der bereits von ExpandoObject vorgesehen ist.

In den beiden Links unten erwähnt, ist es ganz klar, dass mit Hilfe von DynamicObject, es möglich ist, den tatsächlichen Typ (XElement im Beispiel unten Links verwendet wird) zu erhalten / ändern und eine bessere Kontrolle über die Eigenschaften und Methoden.

https://blogs.msdn.microsoft.com/csharpfaq/2009/10/19/dynamic-in-c-4-0-creating-wrappers-with-dynamicobject/

public class DynamicXMLNode : DynamicObject    
{    
    XElement node;

    public DynamicXMLNode(XElement node)    
    {    
        this.node = node;    
    }

    public DynamicXMLNode()    
    {    
    }

    public DynamicXMLNode(String name)    
    {    
        node = new XElement(name);    
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)    
    {    
        XElement setNode = node.Element(binder.Name);

        if (setNode != null)    
            setNode.SetValue(value);    
        else    
        {    
            if (value.GetType() == typeof(DynamicXMLNode))    
                node.Add(new XElement(binder.Name));    
            else    
                node.Add(new XElement(binder.Name, value));    
        }

        return true;    
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)    
    {    
        XElement getNode = node.Element(binder.Name);

        if (getNode != null)    
        {    
            result = new DynamicXMLNode(getNode);    
            return true;    
        }    
        else    
        {    
            result = null;    
            return false;    
        }    
    }    
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top