从表达式获取字符串属性名称
我正在尝试写一个强类型的帮助器,它是这样的:
Html.Lookup(x => x.FooId);
现在我有这个:
public static MvcHtmlString Lookup(this HtmlHelper html, Func expression) { // get string "FooId" here }
谁知道怎么弄这个?
public static class ExpressionsExtractor { public static string Lookup(this HtmlHelper html, Expression> expression) { var memberExpression = expression.Body as MemberExpression; if (memberExpression == null) return null; return memberExpression.Member.Name; } }
然后你会用它来调用它:
var propName = Html.Lookup(x => x.FooId);
又一个代码。
public MvcHtmlString Lookup(this HtmlHelper html, Expression> expression) { return MvcHtmlString.Create(ExpressionHelper.GetExpressionText(expression)); }
使用ExpressionHelper类。 Func是委托,Expression在编译时生成ExpressionTree。 Expression.Compile()返回委托,但Func在运行时不会获得ExpressionTree。
当我在Web项目之外需要此function时,目前使用此类,其中System.Web.Mvc
引用不应存在:
namespace Interreg.Domain{ using System; using System.Linq.Expressions; public class PropertyName{ public static string For( Expression> expression){ var body=expression.Body; return GetMemberName(body); } public static string For( Expression> expression){ var body=expression.Body; return GetMemberName(body); } public static string GetMemberName( Expression expression){ if(expression is MemberExpression){ var memberExpression=(MemberExpression)expression; if(memberExpression.Expression.NodeType== ExpressionType.MemberAccess) return GetMemberName(memberExpression.Expression)+"."+memberExpression.Member.Name; return memberExpression.Member.Name; } if(expression is UnaryExpression){ var unaryExpression=(UnaryExpression)expression; if(unaryExpression.NodeType!=ExpressionType.Convert) throw new Exception(string.Format("Cannot interpret member from {0}",expression)); return GetMemberName(unaryExpression.Operand); } throw new Exception(string.Format("Could not determine member from {0}",expression)); } } }
关于这个问题的好处是 – 当深度超过一个级别时,它不会丢失点数。
有点晚了,但我发布了一个简单的解决方案,它在.Net 4中为我工作。它在第4行处理值类型
public PropertyInfo GetPropertyInfo(Expression> propertyLambda) { var member = propertyLambda.Body as MemberExpression; if (member == null) {// value types return Convert(x.property) which can't be cast to MemberExpression var expression = propertyLambda.Body as UnaryExpression; member = expression.Operand as MemberExpression; } return member.Member as PropertyInfo; }