Svish Svish - 2 months ago 8
C# Question

How to check if two Expression<Func<T, bool>> are the same

Is it possible to find out if two expressions are the same?

Like given the following four expressions:

Expression<Func<int, bool>> a = x => false;
Expression<Func<int, bool>> b = x => false;
Expression<Func<int, bool>> c = x => true;
Expression<Func<int, bool>> d = x => x == 5;


Then, at least we can see that:


  • a == b

  • a != c

  • a != d



But can I do anything to find this out in my code?

Took a peek in the msdn library, where it says that


Equals
: Determines whether the specified Object is equal to the current
Object
. (Inherited from
Object
.)


which I guess means that at least the Expression class hasn't overrided the equals method to become Equatable? So how would you do this? Or am I asking too much here? :p

Answer

You can have a look at the type ExpressionEqualityComparer that is used inside Linq to db4o. It implements the interface IEqualityComparer<T>, so it's usable for generic collections, as well as for a standalone usage.

It uses the type ExpressionComparison to compare two Expressions for equality, and HashCodeCalculation, to compute a hashcode from an Expression.

It all involves visiting the expression tree, so it can be pretty costly if you do it repeatedly, but it can also be quite handy.

The code is available under the GPL or the dOCL

For instance, here's your test:

using System;
using System.Linq.Expressions;

using Db4objects.Db4o.Linq.Expressions;

class Test {

    static void Main ()
    {
        Expression<Func<int, bool>> a = x => false;
        Expression<Func<int, bool>> b = x => false;
        Expression<Func<int, bool>> c = x => true;
        Expression<Func<int, bool>> d = x => x == 5;

        Func<Expression, Expression, bool> eq =
            ExpressionEqualityComparer.Instance.Equals;

        Console.WriteLine (eq (a, b));
        Console.WriteLine (eq (a, c));
        Console.WriteLine (eq (a, d));
    }
}

And it indeed prints True, False, False.