2012-05-06 46 views
13

Estoy aprendiendo C# y MVC, y estoy tratando de entender algunos ejemplos.@ Html.EditorFor (m => m) sintaxis lambda en MVC

@Html.EditorFor(m => m) 

tiempo me di cuenta de que '=>' es el operador lambda, y que significa algo así como "m tal que m". Eso realmente no tiene ningún sentido para mí. ¿Por qué no simplemente pasar en m?

Además, no veo m definido en ninguna vista con la que estoy trabajando. El modelo está definido, y supuestamente eso es lo que este método está recogiendo. ¿Cómo funciona?

Finalmente, miré la definición de Html.EditorFor, y no veo ninguna sobrecarga para pasar en un solo parámetro. ¿Dónde se define esta sintaxis? http://msdn.microsoft.com/en-us/library/ee834942.aspx

+2

"y no ve ninguna sobrecarga para pasar en un solo parámetro" - 'EditorFor' es un método de extensión, por lo que está buscando una sobrecarga con dos parámetros, el primero es" esto ". – hvd

+2

También una cosa que recomendaría al construir un sitio en mvc3 es usar los tipos específicos de editores como '@ Html.TextBoxFor (m => m.name)' esto es para que, si alguna vez quieres un valor predeterminado, trabajará. Donde yo (al menos) no he podido asignar esto a un 'EditorFor'. También TextBox/TextArea etc. admite marcadores de posición entre otras cosas donde 'EditorFor' no. por lo que podría hacer '@ Html.TextBoxFor (m => m.Name, new {placeholder =" John Doe "})' y mvc implementará automáticamente un marcador de posición en los navegadores que lo admitan. – Jared

Respuesta

18

Vamos a desglosar esta información mediante el examen de la firma del método:

MvcHtmlString EditorFor<TModel, TValue>(
    this HtmlHelper<TModel> html, 
    Expression<Func<TModel, TValue>> expression 
) 

Esto es usando la sintaxis de método de extensión, lo que significa que está añadiendo un método llamado EditorFor a HtmlHelper de tal manera que se puede realizar la llamada Html.EditorFor. Pero lo que realmente nos interesa es el segundo parámetro, Expression<Func<TModel, TValue>>. Es un parámetro bastante complicado, pero por ahora podemos ignorar el hecho de que es Expression. Así simplificar, vamos a examinar:

Func<TModel, TValue> expression 

Esto significa que el argumento es cualquier método que tiene un parámetro (de tipo TModel) y el tipo de retorno es TValue. Has estado usando lambdas, que es (esencialmente) una representación más concisa de un método, pero es útil pensar en él como un método ordinario. Por lo que está lambda está tomando un modelo y devolver un modelo:

m => m 

Eso no es tan interesante, así que vamos a comparar a un escenario más realista donde se está volviendo una vivienda sobre el modelo:

m => m.MyStringProperty 

Ahora vamos a comparar con un método estático ordinario se ha declarado en alguna parte:

public static class MyStaticClass 
{ 
    public static string Foo(TModel model) 
    { 
     return model.MyStringProperty; 
    } 
} 

Aunque realmente aquí no sería TModel - sería lo que declaró su tipo de modelo a través del @model. Ahora, por el bien de la discusión, que podría haber en su lugar se utiliza este método en su invocación de EditorFor:

Html.EditorFor(MyStaticClass.Foo); 

Para resumir, lambdas son (en su mayor parte) a poca mano por un método regular. Entonces, lo único que estás haciendo es pasar métodos.

La última nota aquí es que en realidad estamos usando árboles de expresiones, lo que significa que en realidad no está pasando el método, está pasando un modelo de objetos (un árbol de expresiones) que representa el código del método. Esto es, esencialmente, solo usado para descubrir el nombre de la propiedad que estás usando (porque usualmente el lambda sería más como m => m.MyProperty, no simplemente m => m). Esto es todo para evitar cadenas mágicas donde se refiere al nombre de la propiedad usando una cadena (es decir, "MyProperty").

+1

guau, ¡respuesta increíble! La parte que me faltaba es que tienes que usar una expresión que es un nombre de método que devuelve un modelo. Su ejemplo con MyStaticClass fue de gran ayuda para comprender ese concepto. –

3
  1. En el ejemplo, la función lambda no sirve a ningún propósito, cierto. Pero su uso real es para cuando quiere renderizar el editor para una propiedad del modelo: @ Html.EditorFor (m => m.SomeProperty). Las expresiones Lambda son solo una abreviatura de las funciones, pero fuertemente tipadas a través del delegates. El concepto puede ser más familiar desde Javascript:

    myFunction (function (x) {return x.SomeProperty;});

  2. La "m" no está predefinida. Está nombrando el parámetro para la segunda parte de la expresión lambda, y podría ser cualquier cosa: @ Html.EditorFor (whatever => whatever). (Se refiere a lo mismo, en este caso el modelo de la página, independientemente de cómo lo nombre).

  3. El primer parámetro que ve en esas definiciones para Html.EditorFor no es realmente un parámetro. Notará que está utilizando la palabra clave para definir extension methods. Ese parámetro hace referencia al objeto que invocó el método, en este caso, el objeto HtmlHelper < Modelo>.

+0

3. Muy útil, no me di cuenta de que estaba pasando "esto" como el primer parámetro. 2. Todavía estoy un poco desconcertado por esta función lambda, ya que combinada con la respuesta de Kirk Woll, debería devolver un tipo de modelo –

1

Piense en el operador => en el sentido de "va a", por lo (m => m) significa "m va a m", otra forma de decir que vuelva lo mismo m.

En su ejemplo, @Html.EditorFor(m => m), m es un parámetro de entrada anónimo a la expresión lambda m => m, que es un argumento del método extensión EditorFor. Como señaló en su pregunta, ninguna de las sobrecargas de este método toma menos de un parámetro; esto es porque es un Extension Method y el primer parámetro indica el tipo que se extiende. El segundo parámetro es un Expression, y puede usar lambda expresiones para estos.

2

1.

  • @Html.EditorFor(m => m) - editor de pantalla para el modelo de toda
  • @Html.EditorFor(m => m.propertyName) - editor de visualización de propiedad específica del modelo

2.

@Html.EditorFor(m => m) es igual a @Html.EditorFor(t => t) o @Html.EditorFor(randomName => randomName). El nombre no importa, es solo el nombre del parámetro. El tipo para este parámetro es el tipo de modelo de vista.

Tiene que pasar la función, porque no es solo valor, lo que cuenta. Las reflexiones se utilizan para obtener atributos que describen cómo mostrar la propiedad. Mire este ejemplo

public class ResetPasswordModel 
{ 
    public string Username { get; set; } 

    [DataType(DataType.Password)] 
    public string NewPassword { get; set; } 
    [DataType(DataType.Password)] 
    public string PasswordConfirmed { get; set; } 
} 

Los atributos describen que NewPassword debe ser un campo de contraseña, no una entrada normal. Si pasamos el valor, eso no sería posible.

En nuestro ejemplo, @Html.EditorFor(m => m) se mostrará para contener una entrada para el nombre de usuario y dos entradas de contraseña para las contraseñas. @Html.EditorFor(m => m.NewPassword) mostrará la entrada, que tiene el tipo de contraseña.

3.

http://msdn.microsoft.com/en-us/library/ee402949.aspx

public static MvcHtmlString EditorFor<TModel, TValue>(
    this HtmlHelper<TModel> html, 
    Expression<Func<TModel, TValue>> expression 
) 

Este es el método de extensión para la clase HtmlHelper. this HtmlHelper<TModel> html no es un parámetro, es el tipo de clase, esa función se extiende.

Cuestiones relacionadas