Get string property name from expression

前端 未结 4 694
暖寄归人
暖寄归人 2020-12-29 12:07

I\'m trying to write a strongly typed helper which would be something like this:

Html.Lookup(x => x.FooId);

for now I have this:

相关标签:
4条回答
  • 2020-12-29 12:25

    Yet another code.

    public MvcHtmlString Lookup<T, TReturn>(this HtmlHelper<T> html, Expression<Func<T, TReturn>> expression)
    {
      return MvcHtmlString.Create(ExpressionHelper.GetExpressionText(expression));
    }
    

    Use ExpressionHelper class. Func is delegate, Expression is generate ExpressionTree at compile time. Expression.Compile() return delegate, but Func don't get ExpressionTree at runtime.

    0 讨论(0)
  • 2020-12-29 12:30
    public static class ExpressionsExtractor
    {
        public static string Lookup<T, TProp>(this HtmlHelper<T> html, Expression<Func<T, TProp>> expression)
        {
            var memberExpression = expression.Body as MemberExpression;
    
            if (memberExpression == null)
                return null;
    
            return memberExpression.Member.Name;
        }
    }
    

    You would then call it with:

    var propName = Html.Lookup(x => x.FooId);
    
    0 讨论(0)
  • 2020-12-29 12:39

    a bit late but I am posting a simple solution that's working for me in .Net 4. It has handling for value types on line 4

    public PropertyInfo GetPropertyInfo<TSource>(Expression<Func<TSource, object>> 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;
        }
    
    0 讨论(0)
  • 2020-12-29 12:47

    Currently using this class when I need this functionality outside of web project where System.Web.Mvc reference shouldn't exist:

    namespace Interreg.Domain{
      using System;
      using System.Linq.Expressions;
      public class PropertyName{
        public static string For<T>(
          Expression<Func<T,object>> expression){
          var body=expression.Body;
          return GetMemberName(body);
        }
        public static string For(
          Expression<Func<object>> 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));
        }
      }
    }
    

    Good thing about this one is - it does not lose dots when going deeper than just one level.

    0 讨论(0)
提交回复
热议问题