Quiero entender la expresión lambda en @ Html.DisplayFor (modelItem => item.FirstName)

Soy bastante nuevo en C # y MVC y he usado lambdas en ciertas ocasiones, como en métodos anónimos y en LINQ.

Usualmente veo expresiones lambda que se ven así:

(x => x.Name), (x => { Console.WriteLine(x)) 

Entiendo que lambda = “va a”. Nunca he visto una expresión lambda donde el parámetro izquierdo no se usa.

Sin embargo, no sé cómo traducir esta expresión lambda

 @Html.DisplayFor(modelItem => item.FirstName) 

¿Alguien puede arrojar algo de luz sobre este para mí? ¿No debería ser esto?

 (modelItem => modelItem.FirstName)? 

Lo obtuve del tutorial Introducción a ASP.NET MVC de Microsoft.

Una expresión lambda es una forma de escribir una función anónima, es decir, una función sin nombre. Lo que tienes en el lado izquierdo de la “flecha” son los parámetros de la función, y lo que tienes en el lado derecho es el cuerpo de la función. Por lo tanto, (x => x.Name) traduce lógicamente a algo así como la string Function(Data x) { return x.Name } la string tipos y los Data obviamente variarán y se derivarán del contexto.

La ausencia del parámetro del lado izquierdo se traduce en una función sin parámetros, por lo que esto (() => someVariable) traduce lógicamente a esto: string Function() { return someVariable; } string Function() { return someVariable; }

En este punto, puede comenzar a preguntarse, de dónde viene someVariable , no es un parámetro de función y no está definido en la función. Estaría en lo cierto, una función como esta nunca comstackría. Sin embargo, la función lambda como esta está perfectamente bien, ya que permite levantar variables de scope externo y usarlas de esta manera. (Internamente, se crea una clase contenedora donde las variables que se utilizan en la expresión lambda se convierten en campos).

Ahora veamos qué model => item.FirstName significa. Lógicamente, se traduciría en la string Function(Model model) { return item.FirstName; } string Function(Model model) { return item.FirstName; } . Básicamente esta es una función con un parámetro, pero este parámetro no se usa.

Y ahora, la última parte de la información. Aunque las expresiones lambda representan funciones al final, a veces se crean no con el propósito de ser realmente ejecutadas (aunque potencialmente pueden). Una expresión lambda se puede representar en forma de un árbol de expresiones. Esto significa que en lugar de ejecutarlo se puede analizar .

En este caso particular, el motor MVC no ejecuta la función que representa la expresión lambda. En cambio, la expresión se analiza para que el motor MVC sepa qué html debe emitir para esta línea en particular. Si su elemento de datos no proviene directamente de su objeto modelo, la parte izquierda de la expresión lambda no tiene importancia.

Creo que se trata del ciclo foreach. ejemplo:

 @foreach(var item in model) {  @html.displayfor(model => item.firstName)   } 

var item debe usar un var item porque cada elemento de la secuencia es de tipo anónimo. model => item.firstName means (input parameter) => expression . no puede usar el parámetro de entrada porque almacenamos el “elemento” actual en el item .

Está usando una lambada sin parámetros. Ver esta pregunta

Básicamente, DisplayFor no usa el modelo de parámetros de la función lambda (podría ser cualquier cosa que yo dijera use _ o ()) y simplemente utiliza la función lambda dentro del ciclo for para usar displayfor en su contra. DisplayFor requiere una función lambda.

También tuve problemas para entender los códigos generados por Visual Studio. En lugar de proporcionar una explicación general sobre la expresión lambda, me gustaría poner un contexto utilizando ASP.NET MVC framework.

Supongamos que preparamos una clase Model (por ejemplo, Destination) con 2 atributos: City y ProvinceCode.

 public class Destination { public string City { get; set; } public string ProvinceCode { get; set; } } 

Después de generar el Controlador y la Vista, deberíamos obtener los códigos generados por Visual Studio como se mencionó. Sin embargo, los códigos generados son algo difíciles de entender, especialmente para las filas de datos

 @Html.DisplayFor(modelItem => item.City) 

Solo creo que el equipo MVC debería pensar que la clase Html helper debería usarse de manera consistente en el archivo cshtml. Por lo tanto, trataron de usar trucos para pasar el comstackdor de C #. En este caso, modelItem ni siquiera se usa como un parámetro de entrada de esta expresión lambda. No podemos usar () ya que el tipo NO es correcto. Por eso, si reemplazamos el modelo o cualquier objeto modelo, la expresión lambda funciona.

Para ser sincero, me gustaría volver a escribir los códigos generados en una forma más legible. En lugar de utilizar la clase de ayuda Html , podemos simplemente renderizar la salida correcta de la siguiente manera:

 @foreach (var item in Model) {   @* Code Generated by Visual Studio. modelItem is a dummy param *@ @Html.DisplayFor(modelItem => item.City)   @* A better way - simply get rid of Html helper class *@ @item.ProvinceCode   }