2012-04-12 36 views
33

Usando AutoMapper, llegué a un lugar donde un argumento con nombre hubiera ajuste muy bien:¿Por qué un árbol de expresiones no puede contener una especificación de argumento con nombre?

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

Pero el compilador me gritó:

un árbol de expresión 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

25

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

El usuario acepta que espero que las dos últimas líneas deben hacer exactamente lo mismo, ¿verdad? Cuál es imprimir NM3.

Ahora, qué expresión llamadas a las bibliotecas árbol le gustaría que la conversión árbol de expresión para generar asegurar que esto? ¡No hay ninguno! Por lo tanto, nos enfrentamos a las siguientes opciones:

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

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

Elegimos (3).

+0

Este mensaje de error me siento realmente debe ser documentada a este efecto. En otras palabras, buscar msdn para la cadena de mensaje de error exacto debería proporcionarnos esta aclaración. http://social.msdn.microsoft.com/Search/en-US?query=%22An%20expression%20tree%20may%20not%20contain%20a%20named%20argument%20specification%22&ac=8 – payo

+0

Esto es excelente, gracias Eric. En realidad nunca había tomado un vistazo a las diferencias entre 'Expresión <...> 'y' 'Func <...> hasta ahora. Sin embargo, cuando dice que (1) sería costoso, ¿significa esto en términos de costo de desarrollo o que sería computacionalmente costoso? –

+1

@BrandonLinton: sería costoso desarrollar, probar, documentar y mantener, particularmente si se compara con el muy pequeño beneficio que ofrece. Podríamos haber optado por apoyarlo al principio, después de todo, VB siempre tuvo argumentos con nombre para las llamadas a métodos, pero decidimos no hacerlo. –

Cuestiones relacionadas