如何使用和 ExpressionTree 访问 lambda 表达式中 属性 的名称

How do I use and ExpressionTree to access the name of the property in a lambda expression

我正在使用以下方法通过检查生成的 ExpressionTree 来获取在 lambda 中指定的 属性 的名称:

var name =GetPropertyName<Entity1, Entity2>(x => x.Entity2);

public string GetPropertyName<T, P>(Expression<Func<T, P>> expression)
    {
        var memberExpression = expression.Body as MemberExpression;
        var propertyInfo = memberExpression.Member as PropertyInfo;
        return propertyInfo.Name;
    }

//name is "Entity2"

鉴于以下表达式,我想提取名称“Entity2s”、“Entity3s”和“Entity4s”

var names = GetPropertyNames<Entity1, IEnumerable<Entity4>>(x => x.Entity2s.SelectMany(x => x.Entity3s).SelectMany(x  => x.Entity4s));

这是一种从您提供的 Expression 树中提取成员名称的方法。更通用的方法可能应该基于 ExpressionVisitor 子类。

public static List<string> GetPropertyNames<T, P>(Expression<Func<T, P>> fe) {
    var ans = new List<string>();
    var callExpr1 = fe.Body as MethodCallExpression;
    var callExpr2 = callExpr1.Arguments[0] as MethodCallExpression;
    var e2MemberExpr1 = callExpr2.Arguments[0] as MemberExpression;
    ans.Add(e2MemberExpr1.Member.Name);
    var e2MemberExpr2 = (callExpr2.Arguments[1] as LambdaExpression).Body as MemberExpression;
    ans.Add(e2MemberExpr2.Member.Name);
    var e1MemberExpr1 = (callExpr1.Arguments[1] as LambdaExpression).Body as MemberExpression;
    ans.Add(e1MemberExpr1.Member.Name);
    return ans;
}

使用 ExpressionVisitor 就很简单了

 public static List<string> GetPropertyNames<T, P>(Expression<Func<T, P>> expression)
    {
        var visitor = new Visitor();
        visitor.Visit(expression);
        return visitor.Names;
    }

    class Visitor : ExpressionVisitor
    {
        public Visitor()
        {
            Names = new List<string>();
        }

        public List<string> Names { get; }

        protected override Expression VisitMember(MemberExpression node)
        {
            Names.Add(node.Member.Name);
            return base.VisitMember(node);
        }
    }