Как c # определяет, откуда взялась буква «m» (m => m.SomeProperty)? - PullRequest
4 голосов
/ 10 декабря 2010

Например, в приложении MVC я могу использовать Html-помощники для создания метки, подобной этой:

@Html.LabelFor(m => m.ProductName)

Я нигде не объявил переменную "m", но IDE автоматически выясняет, что я пытаюсь сделать. Это несколько смущает, что IDE знает о моем коде больше, чем я. Я бы хотел это исправить.

Я в основном хочу знать, как он знает, как ссылаться на мою модель.

РЕДАКТИРОВАТЬ: Спасибо за все ответы.

Итак, "Html" является экземпляром HtmlHelper. «HTML» является членом базового класса ViewPage. Его значение задается в методе InitHelpers () базового класса ViewPage. Конструктор HtmlHelper принимает ViewContext из ViewPage в качестве параметра. ViewContext знает, какую модель я использую. LabelFor - это метод расширения класса HtmlHelper. И именно поэтому лямбда-выражение знает, как ссылаться на мою модель.

Точки связаны. Спасибо!

Ответы [ 7 ]

12 голосов
/ 10 декабря 2010

Вам нужно прочитать о лямбдах, но происходит то, что вы передаете указатель функции на метод LabelFor. Поскольку Html строго типизирован (HtmlHelper<TYourModelType>) и LabelFor объявлен как Func<TYourModelType, TValue>, компилятор (и IDE) может определить, что m является экземпляром типа вашей модели, и, следовательно, обеспечить хорошие раскрывающиеся списки IDE для членов.

Иногда люди считают полезным сравнить другие синтаксические варианты, которые есть в вашем распоряжении. Например, это будет в равной степени справедливо:

Html.LabelFor(SomePropertyMethod);

...

string SomePropertyMethod(TYourModelType model) 
{
    return model.SomeProperty;
}
1 голос
/ 10 декабря 2010

Универсальный параметр для LabelFor того же типа, что и ваша модель:

Inherits="System.Web.Mvc.ViewPage<MyModel>"

Параметр для LabelFor имеет тип:

Expression<Func<MyModel,TValue>>

Таким образом, компилятор знает, что вы передадите объект MyModel в лямбду.

1 голос
/ 10 декабря 2010

Это объявлено против вашего View наверху.

 <%@ Page Inherits="System.Web.Mvc.ViewPage<MvcApplication1.Models.EntryForm1>" %>

Таким образом, ваша форма наследуется от ViewPage, и она будет понимать, что тип T.

0 голосов
/ 10 декабря 2010

Вы объявили m; Вы разместили лямбда-синтаксис (в форме выражения). Часть перед => - это список параметров для вашей лямбды, а часть после => - это тело.

В вашем случае вы используете выражение лямбда. Это сокращение для:

@Html.LabelFor(m =>
{
    return m.PropertyName;
});

В любом случае параметр m здесь представляет значение, переданное функции.

0 голосов
/ 10 декабря 2010

m => m.ProductName - это лямбда, представляющая анонимный метод , который принимает один параметр, называемый m.Итак, m объявлено : прямо в самой лямбде.Тип должен быть выведен компилятором, учитывая, что тип делегата LabelFor принимает в качестве параметра.

0 голосов
/ 10 декабря 2010

Имя m ничего не значит.@Html.LabelFor(n => n.ProductName) означает то же самое.Это унарная анонимная функция, которая возвращает ProductName своего аргумента.

0 голосов
/ 10 декабря 2010

Очевидно, что LabelFor принимает делегата, чья подпись имеет один аргумент. Среда IDE видит это и на основе этих типов m имеет тот же тип данных, что и аргумент.

...