MVC中的@ Html.EditorFor(m => m)lambda语法

Joh*_*rum 13 c# lambda extension-methods editorfor razor

我只是在学习C#和MVC,并试图了解一些例子.

@Html.EditorFor(m => m)
Run Code Online (Sandbox Code Playgroud)

最终我发现'=>'是lambda运算符,它意味着像"m这样的m".这对我来说没有任何意义.为什么不直接进入?

另外,我没有看到m在我正在使用的任何视图中定义.定义了模型,据称这就是这种方法所采用的方法.这是如何运作的?

最后,我查看了Html.EditorFor的定义,并没有看到任何重载只传递一个参数.这个语法定义在哪里? http://msdn.microsoft.com/en-us/library/ee834942.aspx

Kir*_*oll 18

让我们通过检查方法签名来解决这个问题:

MvcHtmlString EditorFor<TModel, TValue>(
    this HtmlHelper<TModel> html, 
    Expression<Func<TModel, TValue>> expression
)
Run Code Online (Sandbox Code Playgroud)

这是通过使用扩展方法的语法,这意味着它加入了一个名为方法EditorFor来HtmlHelper,这样你可以拨打电话Html.EditorFor.但我们真正感兴趣的是第二个参数,Expression<Func<TModel, TValue>>.这是一个非常复杂的参数,但是现在我们可以忽略这个事实Expression.如此简化,让我们来看看:

Func<TModel, TValue> expression
Run Code Online (Sandbox Code Playgroud)

这意味着参数是任何具有一个参数(类型TModel)且返回类型为的方法TValue.你一直在使用lambdas,它(基本上)是一个方法的更简洁的表示,但将它想象成一个普通的方法是有帮助的.所以你是lambda正在拿一个模型并返回一个模型:

m => m
Run Code Online (Sandbox Code Playgroud)

这不是那么有趣,所以让我们将它与一个更现实的场景进行比较,你将从模型中返回一个属性:

m => m.MyStringProperty
Run Code Online (Sandbox Code Playgroud)

现在让我们将它与您在某处声明的普通静态方法进行比较:

public static class MyStaticClass 
{
    public static string Foo(TModel model) 
    {
        return model.MyStringProperty;
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然真的在这里它不会TModel- 它将是你宣布你的模型类型的任何东西@model.现在,为了便于讨论,您可以在调用时使用此方法EditorFor:

Html.EditorFor(MyStaticClass.Foo);
Run Code Online (Sandbox Code Playgroud)

总而言之,lambdas(在大多数情况下)只是常规方法的简短手.所以你所做的只是传递方法.

这里的最后一点是我们实际上正在使用表达式树,这意味着你实际上并没有传递方法,而是传递了一个表示方法代码的对象模型(表达式树).实际上,这只是用来计算你正在使用的属性名称(因为通常lambda会更像m => m.MyProperty,而不仅仅是m => m).这是为了避免使用字符串(即"MyProperty")引用属性名称的魔术字符串.