如何获取与 LambdaExpression 中使用的属性相对应的变量名称列表?

时间:2021-06-23 15:35:48

标签: c# lambda expression expression-trees

我有一个 LambdaExpression,它有一个 lambda 体,如:

x => x.FirstName == "Joe" And x.LastName == "Bloggs"

它还可以包含更多属性,也可以包含 OR 运算符。

如何获得该 lambda 中使用的所有属性名称的 List<string>

因此,基于上面的 lambda,列表将如下所示:

FirstName
LastName 

还有其他 stackoverflow 页面以某种方式将其 Expression 转换为 MemberExpression,但这对我不起作用,因为它无法正确转换。

我想要做的一个例子就像下面的这个答案,但它返回的是 PropertyInfo 而不是字符串列表:

Retrieving Property name from lambda expression

1 个答案:

答案 0 :(得分:3)

.NET 提供了一个 ExpressionVisitor class,它知道如何下降到树中的子表达式。您可以继承它并覆盖 VisitMember 以获取包含在树中的所有 MemberExpression 实例,而无需关心它们是否通过 &&||== 组合、<、函数调用等

这是一个完整的工作示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Rextester
{
    class MemberCollector : ExpressionVisitor
    {
        public HashSet<string> FoundMembers = new HashSet<string>();
        
        override protected Expression VisitMember (MemberExpression node)
        {
            FoundMembers.Add(node.Member.Name);
            return base.VisitMember(node);
        }
    }
    
    public class Program
    {
        public static void Main(string[] args)
        {
            var collector = new MemberCollector();
            Expression<Func<DateTime, bool>> e = dt => dt.Hour == 12 && dt.Minute % 10 == 0;
            collector.Visit(e);
            foreach (var m in collector.FoundMembers)
                Console.WriteLine(m);
        }
    }
}

我没有过滤成员访问,因此除了属性之外,我还会找到字段和方法访问,但这将是对 node.Member 的直接测试。

相关问题