@формат HTML.EditorFor (m => m) лямбда-синтаксис в MVC

Я просто изучаю C# и MVC и пытаюсь понять некоторые примеры.

@Html.EditorFor(m => m)

В конце концов я понял, что '= > ' является лямбда-оператором, и что это означает что-то вроде "M такое, что m". Для меня это не имеет никакого смысла. Почему бы просто не пройти в М?

кроме того, я не вижу M, определенного в любом представлении, с которым я работаю. Модель определена, и предположительно это то, что этот метод собирает. Как это работает?

наконец, я посмотрел на определение для Html.EditorFor, и не вижу никакой перегрузки для передачи только одного параметра. Где определяется этот синтаксис?? http://msdn.microsoft.com/en-us/library/ee834942.aspx

4 ответов


давайте разберем это, изучив сигнатуру метода:

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

это использует синтаксис метода расширения, что означает, что он добавляет метод с именем EditorFor to HtmlHelper такие, что вы можете сделать вызов Html.EditorFor. Но то, что нас действительно интересует, - это второй параметр,Expression<Func<TModel, TValue>>. Это довольно сложный параметр, но пока мы можем игнорировать тот факт, что это Expression. Так упрощая, давайте рассмотрим:

Func<TModel, TValue> expression

это означает, что аргумент is любой метод, который имеет один параметр (типа TModel) и тип возврата -TValue. Вы использовали lambdas, который (по сути) является более кратким представлением метода, но полезно просто думать об этом как об обычном методе. Таким образом, вы лямбда берет модель и возвращает модель:

m => m

это не так интересно, поэтому давайте сравним его с более реалистичным сценарием, когда вы возвращаете свойство модель:

m => m.MyStringProperty

теперь давайте сравним его с обычным статическим методом, который вы где-то объявили:

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

хотя на самом деле здесь этого не было бы TModel -- это будет то, что вы объявили свой тип модели через @model. Теперь, для обсуждения, вы могли бы вместо этого использовать этот метод в своем вызове EditorFor:

Html.EditorFor(MyStaticClass.Foo);

Итак, подводя итог, лямбды (по большей части) - это просто короткая рука для регулярного метода. Так что все вы делать-это передавать методы.

последнее замечание здесь заключается в том, что мы фактически используем деревья выражений, что означает, что вы фактически не передаете метод, вы передаете объектную модель (дерево выражений), которая представляет код метода. Это, по сути, просто используется, чтобы выяснить имя свойства, которое вы используете (потому что обычно лямбда будет больше похожа на m => m.MyProperty не только m => m). Это все, чтобы избежать волшебных строк, где вы ссылаетесь на имя свойства использование строки (т. е. "MyProperty").


  1. в вашем примере функция lambda не служит никакой цели, true. Но его реальное использование - это когда вы хотите отобразить редактор для свойства модели: @Html.В(м => м. SomeProperty). Лямбда-выражения на самом деле являются просто сокращением для функций, но строго типизированы с помощью представители. Концепция может быть более знакомой из Javascript:

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

  2. "m"не предопределено. Он называет параметр для второй части лямбда-выражения и может быть любым: @Html.В( любой => любой другой ). (Это относится к одному и тому же, в данном случае к модели страницы, независимо от того, как вы ее называете.)

  3. первый параметр, который вы видите в этих определениях для HTML.В не параметр. Вы заметите, что они используют этой ключевое слово для определения методы расширения. Этот параметр ссылается на объект, который вызвал метод, в данном случае HtmlHelper


1.

  • @Html.EditorFor(m => m) - редактор отображения всей модели
  • @Html.EditorFor(m => m.propertyName) - редактор отображения для конкретного свойства модели

2.

@Html.EditorFor(m => m) равна @Html.EditorFor(t => t) или @Html.EditorFor(randomName => randomName). Имя не имеет значения, это просто имя параметра. Тип этого параметра-тип модели представления.

вы должны передать функцию, потому что это не только значение, которое считается. Отражения используется для получения атрибутов, описывающих способ отображения свойства. Посмотрите на этот пример

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

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

атрибуты описывают, что NewPassword должно быть полем пароля, а не обычным вводом. Если мы передадим значение, это будет невозможно.

в нашем примере @Html.EditorFor(m => m) покажет, что содержит один вход для имени пользователя и два ввода пароля для паролей. @Html.EditorFor(m => m.NewPassword) появится входной сигнал, который имеет вид пароль:.

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
)

это метод расширения для класса HtmlHelper. this HtmlHelper<TModel> html не является параметром, это тип класса, эта функция расширяется.


думать => оператор как "идет", так (m => m) означает "m идет к m", другой способ сказать, что вы получаете то же самое m.

в вашем примере @Html.EditorFor(m => m), m - анонимный входной параметр лямбда-выражения m => m, который является аргументом метода расширения EditorFor. Как вы отметили в своем вопросе, ни одна из перегрузок для этого метода не занимает меньше одного параметра; это потому, что это Метод Расширения и первый параметр указывает тип, который он расширяет. Второй параметр -выражение, а вы можете использовать лямбда выражения для этих.