chris
chris

Reputation: 148

How to get a list of variable names corresponding to properties used in a LambdaExpression?

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

Answers (1)

Ben Voigt
Ben Voigt

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

Related Questions