【发布时间】:2010-10-14 21:24:05
【问题描述】:
通过 lambda 表达式传入时,是否有更好的方法来获取属性名称? 这是我目前拥有的。
例如。
GetSortingInfo<User>(u => u.UserId);
仅当属性是字符串时,它才通过将其转换为成员表达式来工作。因为并非所有属性都是字符串,所以我必须使用对象,但它会为这些返回一元表达式。
public static RouteValueDictionary GetInfo<T>(this HtmlHelper html,
Expression<Func<T, object>> action) where T : class
{
var expression = GetMemberInfo(action);
string name = expression.Member.Name;
return GetInfo(html, name);
}
private static MemberExpression GetMemberInfo(Expression method)
{
LambdaExpression lambda = method as LambdaExpression;
if (lambda == null)
throw new ArgumentNullException("method");
MemberExpression memberExpr = null;
if (lambda.Body.NodeType == ExpressionType.Convert)
{
memberExpr =
((UnaryExpression)lambda.Body).Operand as MemberExpression;
}
else if (lambda.Body.NodeType == ExpressionType.MemberAccess)
{
memberExpr = lambda.Body as MemberExpression;
}
if (memberExpr == null)
throw new ArgumentException("method");
return memberExpr;
}
【问题讨论】:
-
更好的代码?我不这么认为。类型检查仅扩展到整个表达式,因此您确实需要在运行时进行检查。 :(
-
是的......只是想知道是否有更好的方法来做到这一点,因为它让我觉得有点 hacky。但如果就是这样,那就太酷了。谢谢。
-
给大家的注意事项:使用此处列出的
MemberExpression方法仅获取成员的name,而不是获取实际的@ 987654326@ 本身,因为返回的MemberInfo在某些“衍生:基本”场景中不能保证是反射类型。见lambda-expression-not-returning-expected-memberinfo。绊了我一次。接受的答案也受此影响。 -
从 C# 6 开始,您可以简单地使用
nameof(),例如:nameof(User.UserId)。不需要辅助方法,它在编译时被替换!
标签: c# linq lambda expression-trees