了解 Func<T, TResult> 使用 MVC 委托
Understanding Func<T, TResult> Delegate with MVC
我正在努力思考 Func < T, TResult> Delegate,但似乎我不清楚。我知道 T 是一个参数 & TResult 是一个 return 类型。
在 MVC 中我一直使用这个函数:
@model Products
@Html.TextBoxFor(s=>s.my_property)
现在 TextBoxFor Function 如何知道传递给我的参数实际上是一个“Products 模型”。
下面是 TextBoxFor Model 的签名:
public static MvcHtmlString TextBoxFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IDictionary<string, Object> htmlAttributes
)
所以我的问题是,当我调用 Html.TextBoxFor(s) 时,这个方法怎么知道 "s" 是一个 "Products" 模型以及 TModel 如何映射到参数 "s"(知道它的产品型号和我需要 return 东西)?
由于 @model Products
指令,Html
属性 (@Html
) 的类型为 HtmlHelper<Products>
。这就是 Razor 引擎的工作原理。
TextBoxFor
是 HtmlHelper<TModel>
的扩展方法,在您的代码中,您在 HtmlHelper<Products>
的实例上调用它,因此 TModel
被解析为Products
.
然后,编译器可以轻松地将 TProperty
绑定到 my_property
的类型,因为它知道 TModel
是什么并且可以推断出 lambda 是什么"returns".
旁注:您必须知道 Expression<Func<T>>
完全 不同于 Func<T>
:
Func<...>
只是一个简单的委托,引用某处的一段可执行代码,即opaque.
另一方面,Expression<Func<...>>
是一个 表达式树 ,它是 AST. 的一种
当您编写 lambda 时,编译器会根据您将 lambda 分配给 Func<...>
还是 Expression<Func<...>>
生成不同的代码。在第一种情况下,它将编译 lambda 并生成一个委托。在第二种情况下,它会发出一个表达式树。
如需更深入的解释,您可以阅读 Eric Lippert 的系列文章 Lambda 表达式与匿名方法:Part 1, Part 2, Part 3, Part 4, Part 5
我正在努力思考 Func < T, TResult> Delegate,但似乎我不清楚。我知道 T 是一个参数 & TResult 是一个 return 类型。
在 MVC 中我一直使用这个函数:
@model Products
@Html.TextBoxFor(s=>s.my_property)
现在 TextBoxFor Function 如何知道传递给我的参数实际上是一个“Products 模型”。
下面是 TextBoxFor Model 的签名:
public static MvcHtmlString TextBoxFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IDictionary<string, Object> htmlAttributes
)
所以我的问题是,当我调用 Html.TextBoxFor(s) 时,这个方法怎么知道 "s" 是一个 "Products" 模型以及 TModel 如何映射到参数 "s"(知道它的产品型号和我需要 return 东西)?
由于 @model Products
指令,Html
属性 (@Html
) 的类型为 HtmlHelper<Products>
。这就是 Razor 引擎的工作原理。
TextBoxFor
是 HtmlHelper<TModel>
的扩展方法,在您的代码中,您在 HtmlHelper<Products>
的实例上调用它,因此 TModel
被解析为Products
.
然后,编译器可以轻松地将 TProperty
绑定到 my_property
的类型,因为它知道 TModel
是什么并且可以推断出 lambda 是什么"returns".
旁注:您必须知道 Expression<Func<T>>
完全 不同于 Func<T>
:
Func<...>
只是一个简单的委托,引用某处的一段可执行代码,即opaque.
另一方面,Expression<Func<...>>
是一个 表达式树 ,它是 AST. 的一种
当您编写 lambda 时,编译器会根据您将 lambda 分配给 Func<...>
还是 Expression<Func<...>>
生成不同的代码。在第一种情况下,它将编译 lambda 并生成一个委托。在第二种情况下,它会发出一个表达式树。
如需更深入的解释,您可以阅读 Eric Lippert 的系列文章 Lambda 表达式与匿名方法:Part 1, Part 2, Part 3, Part 4, Part 5