¿Por qué un árbol de expresiones no puede contener una especificación de argumento con nombre?

c# c#-4.0 expression-trees

Pregunta

Usando AutoMapper, llegué a un lugar donde un argumento con nombre hubiera encajado muy bien:

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

Pero el compilador me gritó:

Un árbol de expresiones no puede contener una especificación de argumento con nombre

Así que tuve que volver a:

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

¿Alguien sabe por qué el compilador no permite argumentos con nombre en esta situación?

Respuesta aceptada

Considera lo siguiente:

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());

Estás de acuerdo, espero que las dos últimas líneas deban hacer exactamente lo mismo, ¿verdad? Que es para imprimir NM3 .

Ahora, ¿a qué biblioteca de expresiones del árbol de llamadas le gustaría que la conversión del árbol de expresiones genere que garantice esto? ¡No hay ninguno! Por lo tanto, nos enfrentamos a las siguientes opciones:

  1. Implementar la característica en la biblioteca del árbol de expresiones. Agregue una transformación en el motor de reducción de árbol de expresiones que conserve el orden de ejecución de los argumentos nombrados. Implementar código en el método de Compile que tenga en cuenta el orden de ejecución.
  2. Haga x = ()=>Q(n : N(), m: M()); en realidad se implementará como x = ()=>Q(M(), N()); y ser incompatible con la versión no-árbol de expresiones.
  3. No permitir argumentos con nombre en los árboles de expresión. Implementar un mensaje de error a tal efecto.

(1) es bonito, pero caro. (2) es un no iniciador; No podemos en buena conciencia introducir este tipo de "gotcha". (3) es barato pero irritante.

Elegimos (3).



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow