Reputation: 148
I have a LambdaExpression
which has a lambda body like:
x => x.FirstName == "Joe" And x.LastName == "Bloggs"
It can also contain more properties and it can also contain OR operators.
How do I get a List<string>
of all the property names used in that lambda?
So the list would look like below based on the lambda above:
FirstName
LastName
There are other stackoverflow pages which somehow cast their Expression
to MemberExpression
, however this does not work for me because it won't cast properly.
An example of what I'm trying to do is like this answer below but that is returning PropertyInfo
rather than a list of strings:
Retrieving Property name from lambda expression
Upvotes: 0
Views: 290
Reputation: 283614
.NET provides an ExpressionVisitor
class that knows how to descend into subexpressions inside the tree. You can inherit from it and override VisitMember
to get all MemberExpression
instances contained in the tree, without caring whether they are combined via &&
, ||
, ==
, <
, function calls, etc.
Here is a complete working example:
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);
}
}
}
I haven't filtered the member accesses so I will find field and method access in addition to properties, but that would be a straightforward test on node.Member
.
Upvotes: 3