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

标签 c# asp.net-mvc razor reflection lambda

我正在尝试按照格式编写我的第一个客户 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);

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

最佳答案

这些是利用 Expression<Func<TModel, TProperty>> 的 3 种不同方式.他们都将提供对属性(property)值(value)的访问。它们在访问表达式树的其余部分和处理成本/效率方面有所不同。

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

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

您将取回属性(property)或 list<property> .当您只想执行表达式并继续前进时,它是最有效的。


ModelMetadata.FromLambdaExpression 使用 Expression<Func<TParameter, TValue>> 类型的表达式作为 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);

这种方法最冗长且效率最低,但您可以获得名称属性类型

MemberExpression.Member 属性授予对 CustomAttributes

的访问权限

关于c# - 从 lambda 表达式访问属性的 HtmlHelper 方法之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29661096/

相关文章:

c# - 奇怪的突然错误 "The number of bytes to be written is greater than the specified ContentLength"

asp.net - 在默认应用程序池中关闭回收是否安全

asp.net-mvc - Razor View 中的 'pattern' 属性警告

c# - ASP.NET Core 2.1 Razor Form,Post 未到达 Controller

c# - 从 C# 将 Delphi 集传递给外部 Delphi 函数

c# - VBO 或显示列表 - GPU 兼容性

c# - 检查文件是否存在于 asp.net mvc 5

javascript - 使用 jquery 显示表中的相邻行

c# - IEnumerable 中的项目在 foreach 内部发生了更改,但更改未保存到集合中

javascript - 如何在 ASP.NET MVC 中重置 &lt;input type ='file'/>