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

Я хочу понять выражение лямбда в @Html.DisplayFor(modelItem => item.FirstName)

Im довольно новый на С# и MVC и использовал lambdas в определенных случаях, например, для анонимных методов и LINQ.

Обычно я вижу лямбда-выражения, которые выглядят примерно так:

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

Я понимаю, что лямбда = "идет". Я никогда не видел лямбда-выражения, где левый параметр не используется.

Я не знаю, как перевести это выражение лямбда, хотя

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

Может ли кто-нибудь пролить свет на меня? Это не должно быть

(modelItem => modelItem.FirstName)?

Я получил это от Microsoft Введение в учебник ASP.NET MVC.

4b9b3361

Ответ 1

Лямбда-выражение - это способ написать анонимную функцию, то есть функцию без имени. То, что у вас на левой стороне "стрелки", это параметры функции, а то, что у вас на правой стороне, - это тело функции. Таким образом, (x => x.Name) логически переводит на что-то вроде string Function(Data x) { return x.Name } типы string и Data, очевидно, будут меняться и быть выведены из контекста.

Отсутствие левого параметра переходит в функцию без параметров, так что этот (() => someVariable) логически переводится на это: string Function() { return someVariable; }

В этот момент вы можете начать задаваться вопросом, откуда приходит someVariable, это не параметр функции, и он не определен в функции. Вы были бы правы, такая функция никогда не будет компилироваться. Однако такая лямбда-функция, как это, совершенно прекрасна, так как позволяет переносить внешние переменные и использовать их таким образом. (Внутри создается класс-оболочка, где переменные, которые используются в лямбда-выражении, становятся полями.)

Теперь посмотрим, что означает model => item.FirstName. Логически это переведет на string Function(Model model) { return item.FirstName; }. В основном это функция с параметром, но этот параметр не используется.

И вот, последний бит информации. Хотя лямбда-выражения представляют собой функции в конце, иногда они создаются не с целью фактического выполнения (хотя, возможно, они и могут). Лямбда-выражение может быть представлено в виде дерева выражений. Это означает, что вместо его выполнения он может быть проанализирован.

В этом конкретном случае MVC-движок не запускает функцию, представленную выражением лямбда. Вместо этого выражение анализируется так, что движок MVC знает, какой html испускает для этой конкретной линии. Если элемент данных не поступает непосредственно из объекта модели, левая часть выражения лямбда не имеет значения.

Ответ 2

Я думаю об этом в цикле foreach. Пример:

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

var item необходимо использовать, потому что каждый элемент в последовательности является анонимным. model => item.firstName означает (input parameter) => expression. вы не можете использовать входной параметр, потому что мы сохраняем текущий "элемент" в item.

Ответ 3

Используется безпараметрическая ламбада. Смотрите question

В основном DisplayFor не использует модель параметра лямбда-функции (это может быть все, что я сказал бы use _ или()), и просто использует функцию лямбда в цикле for, чтобы использовать displayfor против нее. DisplayFor требует функцию лямбда.

Ответ 4

Я также много пытался понять коды, созданные Visual Studio. Вместо того, чтобы дать общее объяснение лямбда-выражения, я хотел бы поместить контекст с использованием структуры ASP.NET MVC.

Предположим, что мы подготовили класс Model (например, Destination) с двумя атрибутами: City и ProvinceCode.

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

После создания Controller и View мы должны получить сгенерированные коды Visual Studio, как упоминалось. Тем не менее, сгенерированные коды несколько трудно понять, особенно для строк данных

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

Я просто догадываюсь, что команда MVC должна думать, что Html-хелпер-класс должен последовательно использоваться в файле cshtml. Таким образом, они пытались использовать трюки для передачи компилятора С#. В этом случае modelItem даже не используется в качестве входного параметра этого лямбда-выражения. Мы не можем использовать(), поскольку тип НЕ правильный. Вот почему, если мы заменим модель или любой объект модели, выражение лямбда работает.

Честно говоря, я хотел бы переписать сгенерированные коды в более читаемой форме. Вместо использования вспомогательного класса Html мы можем просто сделать правильный вывод следующим образом:

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