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

ste*_*-fu 11 c# reflection asp.net-mvc lambda razor

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

public static MvcHtmlString<TModel, TProperty>
    MyHelperFor(this HtmlHelper<TModel> helper, 
    Expression<Func<TModel, TProperty>> expression)
Run Code Online (Sandbox Code Playgroud)

并且似乎有几种不同的方法来访问属性名称和值 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);
Run Code Online (Sandbox Code Playgroud)

var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var propertyName = metadata.PropertyName;
var propertyValue = metadata.Model;
Run Code Online (Sandbox Code Playgroud)

并且

TModel model = (TModel)helper.ViewContext.ViewData.ModelMetadata.Model;
TProperty value = expression.Compile().Invoke(model);
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*ich 10

这些是3种不同的利用方式Expression<Func<TModel, TProperty>>.他们都将获得财产价值.它们在访问表达树的其余部分和处理成本/效率方面各不相同.

使用expression.Compile().Invoke(model)像模型::上的函数一样执行表达式( u => u.name).

TModel model = (TModel)helper.ViewContext.ViewData.ModelMetadata.Model;
TProperty value = expression.Compile().Invoke(model);
Run Code Online (Sandbox Code Playgroud)

你会找回一处房产或list<property>.当您只想执行Expression并继续前进时,它是最有效的.


ModelMetadata.FromLambdaExpression使用类型的表达式Expression<Func<TParameter, TValue>>作为DataDictionary查找.

var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var propertyName = metadata.PropertyName;
var propertyValue = metadata.Model;
Run Code Online (Sandbox Code Playgroud)

这种方法更冗长,效率更低,但您可以访问属性名称.

请注意,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);
Run Code Online (Sandbox Code Playgroud)

这种方法最冗长,效率最低,但您可以获得价值,名称财产类型.

MemberExpression.Member属性提供对 CustomAttributes的访问