从表达式获取字符串属性名称

Omu*_*Omu 11 .net c# asp.net-mvc lambda

我正在尝试写一个强类型帮助器,它将是这样的:

Html.Lookup(x => x.FooId);
Run Code Online (Sandbox Code Playgroud)

现在我有这个:

public static MvcHtmlString Lookup<T,TReturn>(this HtmlHelper<T> html, Func<T, TReturn> expression)
{
     // get string "FooId" here
}
Run Code Online (Sandbox Code Playgroud)

谁知道怎么弄这个?

Dav*_*fer 24

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你会用它来调用它:

var propName = Html.Lookup(x => x.FooId);
Run Code Online (Sandbox Code Playgroud)

  • 这不适用于值类型.使用值类型表达式将是'{x => Convert(x.Property)}'.您需要将其强制转换为UnaryExpression,然后将其操作数强制转换为MemberExpression. (12认同)

小智 14

又一个代码.

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

使用ExpressionHelper类.Func是委托,Expression在编译时生成ExpressionTree.Expression.Compile()返回委托,但Func在运行时不会获得ExpressionTree.


Arn*_*psa 8

当我在Web项目之外需要此功能时,目前使用此类,其中System.Web.Mvc不应存在​​引用:

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));
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

关于这一点的好处是 - 当深度超过一个级别时它不会丢失点.