Search code examples
c#lambdaexpression-trees

What is the difference between Member Expressions and an Expression Tree Generated by a Lambda?


This title might not actually make sense, because these things might be entirely different. First, let me explain why I'm trying to learn about this:

I'm currently trying to write a unit test for a method that touches a lot of properties. Due to that, I'd prefer to write a test that takes in a list of property names as its member data and that will not start randomly failing if someone goes and changes the name of the property. At first, I started with string reflection, but I knew that's a bad idea as it fails that second caveat.

That led me to the following thread and the following code: C# Reflection - Get PropertyInfo without a string

public static string GetPropertyName<T, TReturn>(Expression<Func<T, TReturn>> expression)
{
    MemberExpression body = (MemberExpression)expression.Body;
    return body.Member.Name;
}

This works well with GetValue(), but now I'm trying to understand it. I think I understand how the Expression class basically takes apart the expression lambda and builds a class from it, but I'm trying to understand what the MemberExpression really is and what the difference is with it that allows me to access the name of a class property. I apologize if I'm way off track here.


Solution

  • a MemberExpression is an expression that allows you to access the members of an instance, be a field or a property. It stores the information needed to retrieve that member, such as the host class, member name and type.

    Here is the content of FieldMember and PropertyMember :
    Screenshot generated from LINQPad .Dump().

    enter image description here enter image description here

    Source :

    void Main()
    {
        GetPropertyName<Foo, string>(f => f.Bar);
        GetPropertyName<Foo, string>(f => f.bar);
    }
    
    // Define other methods and classes here
    public static string GetPropertyName<T, TReturn>(Expression<Func<T, TReturn>> expression)
    {
        expression.Dump();
    
        MemberExpression body = (MemberExpression)expression.Body;
        return body.Member.Name;
    }
    
    public class Foo
    {
        public string Bar { get; set; }
        public string bar;
    }