Usando AutoMapper, ho colpito un punto in cui un argomento con nome si sarebbe adattato molto bene:
.ForMember(s => s.MyProperty, opt => opt.MapFrom(s => BuildMyProperty(s, isAdvanced: false)))
Ma il compilatore mi ha urlato:
Una struttura di espressioni non può contenere una specifica argomento con nome
Quindi ho dovuto tornare a:
.ForMember(s => s.MyProperty, opt => opt.MapFrom(s => BuildMyProperty(s, false)))
Qualcuno sa perché il compilatore non consente gli argomenti con nome in questa situazione?
Considera quanto segue:
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());
Sei d'accordo Spero che le ultime due righe debbano fare esattamente la stessa cosa, giusto? Quale è quello di stampare NM3
.
Ora, a quale espressione le chiamate della libreria ad albero ti piacerebbe che la conversione dell'albero delle espressioni generasse ciò che garantisce questo? Non ce ne sono! Pertanto ci troviamo di fronte alle seguenti scelte:
Compile
che tiene conto dell'ordine di esecuzione. x = ()=>Q(n : N(), m: M());
in realtà essere implementato come x = ()=>Q(M(), N());
ed essere incompatibile con la versione dell'albero non di espressione. (1) è bello, ma costoso. (2) è un non-starter; non possiamo in buona coscienza introdurre questo tipo di "gotcha". (3) è economico ma irritante.
Abbiamo scelto (3).