我试图绕着 Func< T,TResult> 代表,但似乎我不清楚。我知道T是一个参数& TResult是一种返回类型。
在MVC中我一直使用这个函数:
@model Products
@Html.TextBoxFor(s=>s.my_property)
现在TextBoxFor函数如何知道传递给我的参数实际上是" 产品模型"。
以下是TextBoxFor Model的签名:
public static MvcHtmlString TextBoxFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IDictionary<string, Object> htmlAttributes
)
所以我的问题是,当我调用Html.TextBoxFor(s)时,为什么这个方法知道&#34; s&#34;是&#34;产品&#34;模型以及TModel如何映射到参数&#34; s&#34; (知道它的产品型号和我需要退货)?
答案 0 :(得分:4)
由于Html
指令,@Html
属性(HtmlHelper<Products>
)的类型为@model Products
。这就是Razor引擎的工作原理。
TextBoxFor
是HtmlHelper<TModel>
的扩展方法,在您的代码中,您在HtmlHelper<Products>
的实例上调用它,因此TModel
已解析为{{ 1}}。
然后,编译器可以轻松地将Products
绑定到TProperty
的类型,因为它知道my_property
是什么,并且可以推断出lambda “返回”< / em>的
附注:您必须知道TModel
完全 与Expression<Func<T>>
不同:
Func<T>
只是一个简单的委托,是对某个可执行代码的引用,它是 opaque 。Func<...>
是一个表达式树,它是一种AST。编写lambda时,编译器会生成不同的代码,具体取决于您是将lambda分配给Expression<Func<...>>
还是Func<...>
。在第一种情况下,它将编译lambda并生成委托。在第二种情况下,它将发出一个表达式树。
有关深入解释,您可以阅读Eric Lippert的系列 Lambda表达式与匿名方法:Part 1,Part 2,Part 3,{{ 3}},Part 4