Was ist der Unterschied zwischen expression.bind und expression.assign (oder: was ist das Besondere an MemberBinding)?

8

Also, das ist in die Schrauben und Muttern, aber ich hoffe, dass jemand hier eine Einsicht haben kann.

Hier ist, was ich geschafft habe zu sammeln (obwohl ich natürlich falsch liegen könnte, also bitte korrigiert mich)

  

Expression.Bind

     
    

Aufgrund meiner Nachforschungen, einschließlich des MSDN-Eintrags zu [topic] [1], scheint es, dass die Expression.Bind-Methode verwendet wird, um einen Ausdruck vom Typ MemberAssignment zu generieren, der ein spezifischer Subtyp von MemberBinding-Ausdrücken ist. Die Methode verwendet MemberInfo und den Ausdruck, an den sie gebunden werden soll. Der resultierende MemberAssignment-Ausdruck repräsentiert die Initialisierung eines Members.

  
     

Ausdruck.Assign

     
    

Ist eine Methode, die eine BinaryExpression erstellt, die eine Zuweisungsoperation darstellt

  

Hier sind meine Fragen: Warum können wir nicht einfach Expression.Assign verwenden, wenn wir Bindungen an die Expression.MemberInit-Methode liefern? Statt:

%Vor%

Zum Beispiel könnten wir einfach folgendes tun:

%Vor%

Ich weiß, dass der Compiler sich beschweren wird, aber ich frage mich, ob es hier mehr als ein syntaktisches Problem gibt. Anders gesagt, geben Expression.Bind / MemberBindings uns etwas Zusätzliches unter die Haube? Oder sind sie nur syntaktischer Zucker, der es einfacher macht, Mitgliederinitialisierungen zu verwalten?

Könnte es noch genauer gesagt dazu beitragen, die Beziehung zwischen Geschäftsobjekten und den zugrunde liegenden Entitäten in .NET EF4 zu verfolgen? Passt es irgendwie in "Arbeiten mit Proxies" im Entity Framework oder hilft es bei der Änderungsverfolgung oder der Brücke zwischen dem Geschäftsobjekt und der EF-basierten Datenzugriffsschicht?

Wie Sie wahrscheinlich voraussehen können, versuche ich, die Erstellung meiner Geschäftsobjekte programmatisch von der zugrunde liegenden Komponente Entities zu verdrahten, und solche Ausdrücke (insbesondere die MemberInit-Methode) können mit dem Erstellungsbit sicher helfen.

Ich war mir jedoch nicht sicher, ob EF / .NET schlau genug ist, diese Bindungen für das Tracking zu verwenden. Oder, ob ich die gleichen Bindungen zur Biz & lt; - & gt; Ent-Verfolgung / Brücke wiederverwenden könnte.

Ich hoffe, das ergab einen Sinn. Wenn etwas unklar ist, würde ich gerne mehr Informationen geben.

Danke !!

    
HoneyBuddha 05.08.2013, 07:13
quelle

1 Antwort

9

Der Objektinitialisierer ist ein komplexer syntaktischer Zucker ... Es ist nur syntaktischer Zucker, denn auf der IL-Ebene gibt es nichts, was einem Objektinitialisierer ähnelt ... Es gibt keine speziellen Anweisungen ... Nur der C # -Compiler schreibt die Anweisungen in einer bestimmten Reihenfolge, aber der gleiche Code könnte ohne OI geschrieben werden. Leider wird selten die genaue Funktionsweise dieses Zuckers beschrieben.

Und jetzt zeige ich Ihnen, warum es komplexer syntaktischer Zucker ist!

Sie könnten das denken:

%Vor%

wird in

übersetzt %Vor%

Aber in Wahrheit wissen Sie, dass es nicht ... sagen wir, dass foo eine Eigenschaft ist ... Sicherlich wird nicht zweimal darauf zugegriffen (ein Schreibvorgang zum Speichern von new Foo() und ein Lesezugriff für%) co_de%) ...

Also könnte / sollte der Code gleich sein:

%Vor%

Aber in Wahrheit ist es nicht! Es ist wahrscheinlich ähnlich wie

%Vor%

Der Unterschied besteht darin, dass, wenn der Setter von foo.Bar eine Ausnahme auslöst, Foo.Bar nicht gesetzt ist!

Sie können es versuchen unter: Ссылка

Der Quellcode:

%Vor%

Dieser nicht so untergeordnete Unterschied, der zu der Komplexität des syntaktischen Zuckers hinzukommt, ist sicherlich mehr als genug, um ein "spezielles" foo zu erzeugen, das nur dafür gebaut ist (das Expression ).

Die Expression.MemberInit ist dann notwendig, weil sie genau das Arbeiten des Objektinitialisierers simulieren wollten und Sie im Objektinitialisierer keinen Zugriff auf das "This" des neuen Objekts haben. Du kannst nicht schreiben:

%Vor%

und sie wollten nicht, dass Sie Ausdrücke wie

schreiben können %Vor%

das wäre möglich, wenn das Expression.Bind einfach ein Array von Expression.MemberInit akzeptiert.

Zweiter Punkt ... Expression.Assign ist in .NET 3.5 (und es ist notwendig, weil die Elementinitialisierung in LINQ ziemlich gebraucht wird), Expression.MemberInit ist nur in .NET 4.0. Ausdrucksbäume wurden für LINQ erstellt und erstellt (mindestens LINQ minus LINQ to Objects, da LINQ to Objects keine Ausdrucksbäume verwendet). Expression.Assign war nicht notwendig, daher wurde es nicht implementiert. Expression.Assign war notwendig, also wurde es implementiert.

Dritter Punkt ... member initialization ist etwas, das in LINQ ziemlich üblich ist, also war es sicherlich schwieriger, alle Ausdrücke aus den "base" -Teilen der Member-Initialisierung (eine temporäre Variable, einige Zuweisungen, ...) zu erstellen (und diese Ausdrücke, wenn Fehler behoben wurden, waren sicherlich komplexer) als eine vordefinierte Methode "All-in-One".

Vierter Punkt ... LINQ-Provider implementieren normalerweise nicht alle möglichen Expression.MemberInit (s) und müssen oft mit der Tatsache arbeiten, dass der Ausdruck remote in einer komplett anderen Umgebung ausgeführt wird (siehe z. B. Beispiel LINQ-to-SQL, das LINQ-Abfragen auf einem SQL Server ausführt). Expression ist viel begrenzter als Expression.MemberInit , daher ist es einfacher von einem LINQ-Provider zu implementieren.

Wähle also einige dieser Gründe aus ... Sie sind alle ziemlich gut und wahrscheinlich würde einer von ihnen allein ausreichen, um ein Expression.Assign zu implementieren. Vier von ihnen zusammen?

    
xanatos 05.08.2013, 14:59
quelle

Tags und Links