Search code examples
c#lambdaexpression-trees

Building an Expression that checks if two properties of the object are equal?


I'm trying to understand how Expressions work, so I imagined a method that takes an object that has two int properties and return boolean value indicate if they are equal, something like:

bool AreEqual(Foo foo)
{
    return foo.Value1 == foo.Value2;
}

here's the Expression I built:

//build the parameter expression of the object
ParameterExpression parameter = Expression.Parameter(typeof(Foo), "x");
//the left member
MemberExpression leftMember = Expression.Property(parameter, "Value1");
//the right member
MemberExpression rightMember = Expression.Property(parameter, "Value2");
//the left lambda
LambdaExpression leftLmbda = Expression.Lambda(leftMember, parameter);
//the right lambda
LambdaExpression rightLambda = Expression.Lambda(rightMember, parameter);
//and here I evaluate the boolean expression:
Expression equalExpression = Expression.Equal(rightLambda, leftLmbda);
//the lambda of the equal expression
LambdaExpression lambda = Expression.Lambda(equalExpression, parameter);

//the object:
Foo foo = new Foo { Value1= 5, Value2=5 };

Delegate expression = lambda.Compile();
var eq = expression.DynamicInvoke(foo);

but it always evaluates to false.

My guess is that I only build one lambda, but don't know how to handle both properties within one lambda


Solution

  • Your Expression.Equal statment should be comparing the two member expressions.

    //build the parameter expression of the object
    ParameterExpression parameter = Expression.Parameter(typeof(Foo), "x");
    //the left member
    MemberExpression leftMember = Expression.Property(parameter, "Value1");
    //the right member
    MemberExpression rightMember = Expression.Property(parameter, "Value2");
    //and here I evaluate the boolean expression:
    Expression equalExpression = Expression.Equal(leftMember, rightMember);
    //the lambda of the equal expression
    LambdaExpression lambda = Expression.Lambda(equalExpression, parameter);
    
    //the object:
    Foo foo = new Foo { Value1 = 5, Value2 = 5 };
    
    Delegate expression = lambda.Compile();
    var eq = expression.DynamicInvoke(foo);