2012-04-12 5 views
33

Mit AutoMapper, traf ich einen Ort, an dem ein benanntes Argument passen sehr schön haben würde:Warum kann ein Ausdrucksbaum keine benannte Argumentspezifikation enthalten?

.ForMember(s => s.MyProperty, opt => opt.MapFrom(s => BuildMyProperty(s, isAdvanced: false))) 

aber der Compiler schrie mich an:

Ein Ausdruck Baum keine benannte Argument-Spezifikation enthalten

Also musste ich zurückkehren:

.ForMember(s => s.MyProperty, opt => opt.MapFrom(s => BuildMyProperty(s, false))) 

Weiß jemand, warum der Compiler in dieser Situation benannte Argumente nicht zulässt?

Antwort

25

Beachten Sie Folgendes:

static int M() { Console.Write("M"); return 1; } 
static int N() { Console.Write("N"); return 2; } 
static int Q(int m, int n) { return m + n; } 
... 
Func<int> f =()=>Q(n : N(), m: M()); 
Expression<Func<int>> x =()=>Q(n : N(), m: M()); 
Func<int> fx = x.Compile(); 
Console.WriteLine(f()); 
Console.WriteLine(fx()); 

Sie bestätigen, hoffe ich, dass die letzten beiden Zeilen die gleiche Sache genau tun müssen, nicht wahr? Welches ist zu drucken NM3.

Nun, welche Expression Tree Library-Aufrufe möchten Sie die Expression Tree Conversion zu generieren, dass dies sicherstellen? Da sind keine! Daher stehen wir vor der folgenden Auswahl:

  1. Implementieren Sie das Feature in der Ausdrucksbaumbibliothek. Fügen Sie eine Transformation in der Ausdrucksbaumstruktur hinzu, die die Engine verringert, die die Reihenfolge der Ausführung der benannten Argumente beibehält. Implementieren Sie Code in der Compile-Methode, die die Ausführungsreihenfolge berücksichtigt.
  2. Make x =()=>Q(n : N(), m: M()); tatsächlich als x =()=>Q(M(), N()); implementiert werden und inkompatibel mit der Nicht-Ausdruck-Struktur-Version sein.
  3. Keine benannten Argumente in Ausdrucksbäumen zulassen. Implementieren Sie eine entsprechende Fehlermeldung.

(1) ist nett, aber teuer. (2) ist ein Nichtstarter; Wir können diese Art von "Gotcha" nicht mit gutem Gewissen einführen. (3) ist billig, aber irritierend.

Wir wählten (3).

+0

Diese Fehlermeldung, die ich fühle, sollte wirklich zu diesem Einfluss dokumentiert werden. Mit anderen Worten, die Suche in msdn nach der genauen Fehlermeldung sollte uns diese Klarstellung liefern. http://social.msdn.microsoft.com/Search/en-US?query=%22An%20expression%20tree%20may%20not%20contain%20a%20named%20argument%20specification%22&ac=8 – payo

+0

Das ist ausgezeichnet - danke Eric. Ich habe mir die Unterschiede zwischen 'Expression <...>' und' Func <...>' bisher nicht wirklich angesehen. Wenn Sie sagen, dass (1) teuer wäre, bedeutet dies jedoch, dass es sich um Entwicklungskosten handelt oder dass es rechenintensiv wäre? –

+1

@BrandonLinton: Es wäre teuer zu entwickeln, zu testen, zu dokumentieren und zu warten, besonders im Vergleich zu dem sehr kleinen Vorteil, den es bietet. Wir hätten uns anfangs entscheiden können, es zu unterstützen - schließlich hatte VB immer Argumente für Methodenaufrufe benannt - aber wir haben es nicht gewählt. –

Verwandte Themen