从 lambda 表达式访问属性的 HtmlHelper 方法之间的区别

Posted

技术标签:

【中文标题】从 lambda 表达式访问属性的 HtmlHelper 方法之间的区别【英文标题】:Difference between HtmlHelper methods for accessing properties from lambda expression 【发布时间】:2015-06-22 01:19:57 【问题描述】:

我正在尝试按照格式编写我的第一个客户 html Helper 扩展方法

public static MvcHtmlString<TModel, TProperty>
    MyHelperFor(this HtmlHelper<TModel> helper, 
    Expression<Func<TModel, TProperty>> expression)

似乎有几种不同的方法可以从expression 访问属性名称和值

var body = expression.Body as MemberExpression;
var propertyName = body.Member.Name;
var propertyInfo = typeof(TModel).getProperty(propertyName)
var propertyValue = propertyInfo.GetValue(helper.ViewData.Model);

var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var propertyName = metadata.PropertyName;
var propertyValue = metadata.Model;

还有

TModel model = (TModel)helper.ViewContext.ViewData.ModelMetadata.Model;
TProperty value = expression.Compile().Invoke(model);

有人可以解释这些方法之间的区别吗?有没有比其他人优越的情况?

【问题讨论】:

如果您检查 MVC source code 中的 System.Web.Mvc.Html,您会发现助手都使用第二个变体 - ModelMetadata.FromLambdaExpression(expression, html.ViewData);,所以我认为这是更好的方法 【参考方案1】:

这是使用Expression&lt;Func&lt;TModel, TProperty&gt;&gt; 的3 种不同方式。他们都将获得财产价值。它们在访问表达式树的其余部分和流程成本/效率方面各不相同。

使用expression.Compile().Invoke(model) 可以像在模型上的函数一样执行表达式 :: ( u =&gt; u.name)

TModel model = (TModel)helper.ViewContext.ViewData.ModelMetadata.Model;
TProperty value = expression.Compile().Invoke(model);

您将取回财产或list&lt;property&gt;。当您只想执行表达式并继续前进时,它是最有效的。


ModelMetadata.FromLambdaExpression 使用Expression&lt;Func&lt;TParameter, TValue&gt;&gt; 类型的表达式作为DataDictionary 查找。

var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var propertyName = metadata.PropertyName;
var propertyValue = metadata.Model;

这种方法更冗长且效率较低,但您可以访问属性 valuename

请注意,ModelMetadata 还允许您访问模型的注释值,例如 ValidatorsDisplayName


MemberExpression 使用表达式来访问字段/属性及其类型。

var body = expression.Body as MemberExpression;
var propertyName = body.Member.Name;
var propertyInfo = typeof(TModel).getProperty(propertyName)
var propertyValue = propertyInfo.GetValue(helper.ViewData.Model);

这种方法最冗长,效率最低,但您会得到 valuenameproperty type

MemberExpression.Member 属性允许访问 CustomAttributes

【讨论】:

以上是关于从 lambda 表达式访问属性的 HtmlHelper 方法之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

从 lambda 表达式中获取属性名称*没有*对象实例

如何从字符串为深层属性创建表达式树/lambda

从 HtmlHelper 的扩展方法中传递的 lambda 表达式中获取属性值的最简单方法是啥?

用于从实体类及其导航属性中选择多个列的 Linq Lambda 表达式

java-07 内部类匿名内部类局部内部类lambda

2017-6-1 Linq表达式 Lambda 表达式