在试图理解TextBoxFor()
时,我在 MSDN 中遇到了这个定义......
TextBoxFor<TModel, TProperty>(HtmlHelper<TModel>, Expression<Func<TModel, TProperty>>, IDictionary<String, Object>)
这只是一个泛型类,还是其他东西,还是非 c#?
(尖括号内的尖括号让我失望)
以及你如何解释它(一个链接就可以了——只要它对 C# 等的初学者都可以)。
在试图理解TextBoxFor()
时,我在 MSDN 中遇到了这个定义......
TextBoxFor<TModel, TProperty>(HtmlHelper<TModel>, Expression<Func<TModel, TProperty>>, IDictionary<String, Object>)
这只是一个泛型类,还是其他东西,还是非 c#?
(尖括号内的尖括号让我失望)
以及你如何解释它(一个链接就可以了——只要它对 C# 等的初学者都可以)。
这是嵌套泛型类型参数的示例。
Expression<T>
是一个开放的泛型类,它采用单个类型参数。
Func<TModel, TProperty>
是一个具体的泛型委托类型,它引用来自周围泛型函数的类型参数。
它只是一个嵌套的泛型类型。
Expression
类型的Func
类型TModel, TProperty
这是一堂课。
Expression<Func<TModel, TProperty>>
封装Func<TModel, TProperty>
,并包含额外的元数据,第三方可以使用这些元数据Func
以他们自己的母语重建。
Func<TSrc, TDest>
表示一个函数,该函数将TSrc
其作为输入,并生成一个实例TDest
作为其输出. 例如,我可以说:
var addOne = new Func<int, int>(i => i + 1);
并且addOne
将是一个采用整数并返回该整数加一的映射。在你定义它之后,你可以调用addOne(1)
,你会期望它给你 2。
括号内的东西—— i => i + 1——是一段称为 lambda 的语法。令人困惑的是,一个 lambda 可以用来表示 aFunc<TSrc, TDest>
和 an Expression<Func<TSrc, TDest>>
。也就是说,根据上下文,
i => i + 1
代表一个Func<int, int>
对象或一个Expression<Func<int, int>>
对象。这是语言中同音性的一个例子(我最喜欢的例子) 。也就是说,一种语法,您可以使用相同的符号或图标表示不同类的对象。
回到 MVC,它想要一个Expression<Func<TModel, TProperty>>
而不只是一个旧计划的原因Func<TModel, TProperty>
是因为它想要了解更多关于属性的信息,而不是该属性对模型实例的作用:它想要知道额外的数据,例如属性名称、它的属性,以及它使用什么样的错误处理。所以你可以给它类似的东西
@Html.TextBoxFor(m => m.FirstName, ...)
MVC 将在您的模型中查找该属性FirstName
,并根据您在该属性上定义的属性构建各种 HTML。
这或多或少是这样工作的。
具有嵌套泛型类型参数的类。
内部部分:
Func<TModel, TProperty>
一个委托,引用(“描述”)一个将泛型类型TModel
作为参数并返回泛型类型结果的函数TProperty
,例如:
TProperty MyFunc(TModel model)
...它对应于通常参数中的类型TextBoxFor()
:
model => model.Name
model
是 类型TModel
并且model.Name
是 类型TProperty
。
外部:
Expression<T>
描述类型的 lambda 表达式(委托)的表达式树T
。泛型类允许您(Expression<T>
简而言之)在运行时检查代码本身,而不是执行它的结果。换句话说,该TextBoxFor()
方法可以例如提取属性的实际名称(Name
在上面的示例中),此外还可以编译表达式并执行它以获得结果。
如果我们简单地将 aFunc<>
作为参数,我们将只能调用传递的委托并获得该调用的结果,而不是仔细检查它。
对于 HTML 帮助器,表达式树的使用主要是一种类型安全的替代TextBox()
方法,这些方法将属性名称作为字符串。
所以,结合起来:
Expression<Func<TModel, TProperty>>
一个参数TextBoxFor()
是“一个表达式树描述:一个 lambda 表达式,它接受泛型类型的参数TModel
并返回泛型类型的属性TProperty
”。
嵌套泛型并不局限于像表达式树这样相对高级的东西。嵌套泛型的一个更简单、具体的示例是:
Dictionary<string, List<int>>
一个字典,其中string
s 为键,List
s 中的int
s 为值。