MVC中的@ Html.EditorFor(m => m)lambda语法
我只是在学习C#和MVC,并试图了解一些例子。
@Html.EditorFor(m => m)
最终我发现’=>’是lambda运算符,它意味着像“m这样的m”。 这对我来说没有任何意义。 为什么不直接进入?
另外,我没有看到m在我正在使用的任何视图中定义。 定义了模型,据称这就是这种方法所采用的方法。 这是如何运作的?
最后,我查看了Html.EditorFor的定义,并没有看到只传递一个参数的任何重载。 这个语法定义在哪里? http://msdn.microsoft.com/en-us/library/ee834942.aspx
让我们通过检查方法签名来解决这个问题:
MvcHtmlString EditorFor( this HtmlHelper html, Expression> expression )
这是使用扩展方法语法,这意味着它将一个名为EditorFor
的方法添加到HtmlHelper
,以便您可以调用Html.EditorFor
。 但我们真正感兴趣的是第二个参数, Expression
。 这是一个非常复杂的参数,但是现在我们可以忽略它是一个Expression
的事实。 如此简化,让我们来看看:
Func expression
这意味着参数是任何具有一个参数( TModel
类型)且返回类型为TValue
。 你一直在使用lambdas,它(基本上)是一种方法的更简洁的表示,但将它看作普通方法是有帮助的。 所以你是lambda正在拿一个模型并返回一个模型:
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);
总而言之,lambdas(在大多数情况下)只是常规方法的一小部分。 所以你所做的就是传递方法。
这里的最后一点是我们实际上正在使用表达式树,这意味着你实际上并没有传递方法,而是传递了一个表示方法代码的对象模型(表达式树)。 实质上,这只是用来计算你正在使用的属性名称(因为通常lambda更像m => m.MyProperty
,而不仅仅是m => m
)。 这是为了避免使用字符串(即“MyProperty”)引用属性名称的魔术字符串。
-
在您的示例中,lambda函数不起任何作用,为true。 但它真正的用途是当你想要为模型的属性渲染编辑器时:@ Html.EditorFor(m => m.SomeProperty)。 Lambda表达式实际上只是函数的简写,但是通过委托强类型化。 Javascript中的概念可能更为熟悉:
myFunction(function(x){return x.SomeProperty;});
-
“m”未预定义。 它为lambda表达式的第二部分命名参数,可以是任何东西:@Html.EditorFor(无论=>等等)。 (它指的是相同的东西,在这种情况下是页面的模型,不管你的名字是什么。)
-
您在Html.EditorFor的定义中看到的第一个参数实际上不是参数。 您会注意到他们正在使用this关键字来定义扩展方法 。 该参数引用调用该方法的对象,在本例中为HtmlHelper
对象。
1。
-
@Html.EditorFor(m => m)
– 整个模型的显示编辑器 -
@Html.EditorFor(m => m.propertyName)
– 显示模型特定属性的编辑器
2。
@Html.EditorFor(m => m)
等于@Html.EditorFor(t => t)
或@Html.EditorFor(randomName => randomName)
。 名称无关紧要,它只是参数的名称。 此参数的类型是视图模型的类型。
你必须传递函数,因为它不仅仅是值,重要的。 reflection用于获取描述如何显示属性的属性。 看看这个例子
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( this HtmlHelper html, Expression> expression )
这是HtmlHelper类的扩展方法。 this HtmlHelper
不是一个参数,它是类的类型,该函数扩展。
将=>
运算符视为“转到”的意思,因此(m => m)
表示“m转到m”,另一种说法是你回到同样的事情。
在您的示例中, @Html.EditorFor(m => m)
, m
是lambda表达式m => m
的匿名输入参数,它是扩展方法EditorFor
的参数。 正如您在问题中所指出的,此方法的重载都不会超过单个参数; 这是因为它是一个扩展方法 ,第一个参数表示它扩展的类型。 第二个参数是Expression ,您可以使用lambda 表达式 。