Подтвердить что ты не робот

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

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

@Html.EditorFor(m => m)

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

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

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

4b9b3361

Ответ 1

Позвольте сломать это, рассмотрев подпись метода:

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

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

Func<TModel, TValue> expression

Это означает, что аргументом является любой метод, который имеет один параметр (типа 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" ).

Ответ 2

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

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

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

  • Первый параметр, который вы видите в этих определениях для Html.EditorFor, на самом деле не является параметром. Вы заметите, что они используют ключевое слово this, чтобы определить методы расширения. Этот параметр ссылается на объект, который вызвал метод, в этом случае объект HtmlHelper <Model> .

Ответ 3

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 не является параметром, это тип класса, который расширяет эту функцию.

Ответ 4

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

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