问题描述
我有一个 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
解决方法
.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
的直接测试。