How to check if two Expression<Func<T, bool>> are the same [duplicate]
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.
As a lazy answer, you can check ToString()
- it should at least indicate where they are clearly different (although it will include the var-name in there, so that would have to be the same).
For checking equivalence accurately... much harder - a lot of work, over a lot of different node types.
It strikes me that this might be difficult to do, except in the simplest of cases.
For example:
var numbers1 = Enumerable.Range(1, 20);
Expression<Func<int, IEnumerable<int>>> a = x => numbers1;
var numbers2 = Enumerable.Range(1, 20);
Expression<Func<int, IEnumerable<int>>> b = x => numbers2;
Technically, these are equal, but how could it be determined without evaluating the IEnuemrable returned in each expression?