53

我是 C# 和 MVC 的新手,并且在某些场合使用过 lambda,例如匿名方法和 LINQ。

通常我看到的 lambda 表达式看起来像这样:

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

我知道 lambda =“去”。我从未见过不使用 left 参数的 lambda 表达式。

我不知道如何翻译这个 lambda 表达式

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

任何人都可以为我阐明这一点吗?这不应该是

(modelItem => modelItem.FirstName)?

我从 Microsoft 的Introduction to ASP.NET MVC 教程中得到了这个。

4

4 回答 4

103

lambda 表达式是一种编写匿名函数的方法,即没有名称的函数。“箭头”左侧是函数参数,右侧是函数体。因此,逻辑上转换为类型之类的(x => x.Name)东西,并且显然会有所不同并从上下文中派生出来。string Function(Data x) { return x.Name }stringData

左侧参数的缺失转换为没有参数的函数,因此这在(() => someVariable)逻辑上转换为:string Function() { return someVariable; }

此时你可能会开始疑惑,someVariable它从何而来,它不是函数参数,也没有在函数中定义。你是对的,这样的函数永远不会编译。然而,像这样的 lambda 函数非常好,因为它允许以这种方式提升和使用外部范围变量。(在内部创建了一个包装类,其中 lambda 表达式中使用的变量成为字段。)

现在让我们看看是什么model => item.FirstName意思。从逻辑上讲,它会转换为string Function(Model model) { return item.FirstName; }. 基本上这是一个带参数的函数,但没有用到这个参数。

现在,最后一点信息。尽管 lambda 表达式最终代表函数,但有时创建它们的目的并不是为了实际执行(尽管它们可能可以)。lambda 表达式可以用表达式树的形式表示。这意味着它可以被解析而不是执行它。

在这种特殊情况下,MVC 引擎不会运行lambda 表达式所代表的函数。而是解析表达式,以便 MVC 引擎知道要为该特定行发出什么 html。如果您的数据项不是直接来自模型对象,则 lambda 表达式的左侧部分无关紧要。

于 2012-04-11T00:20:42.663 回答
7

我认为这是关于 foreach 循环。例子:

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

var item需要使用,因为序列中的每一项都是匿名类型。 model => item.firstName意味着(input parameter) => expression。您不能使用输入参数,因为我们将当前“项目”存储在item.

于 2012-04-11T00:25:25.307 回答
5

它使用的是无参数的lambada。看到这个问题

基本上 DisplayFor 不使用 lambda 函数参数模型(它可以是我所说的使用 _ 或 () 的任何东西),而只是在 for 循环中使用 lambda 函数来针对它使用 displayfor。DisplayFor 需要一个 lambda 函数。

于 2012-04-10T23:48:39.927 回答
1

我也费了很大劲才理解 Visual Studio 生成的代码。我不想提供关于 lambda 表达式的一般解释,而是想使用 ASP.NET MVC 框架放置一个上下文。

假设我们准备了一个具有 2 个属性的模型类(例如 Destination):City 和 ProvinceCode。

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

生成控制器和视图后,我们应该如前所述通过 Visual Studio 获取生成的代码。然而,生成的代码有点难以理解,尤其是对于数据行

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

我只是猜测MVC 团队应该认为 Html 辅助类应该在 cshtml 文件中始终使用。因此,他们尝试使用技巧来通过 C# 编译器。在这种情况下,modelItem 甚至没有用作这个 lambda 表达式的输入参数。我们不能使用 () 因为类型正确。这就是为什么如果我们替换模型或任何模型对象,lambda 表达式就可以工作。

老实说,我想以更易读的形式重写生成的代码。我们可以简单地呈现正确的输出,而不是使用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>
}
于 2017-02-07T06:49:18.203 回答