如何检查两个Expression <Func <T,bool >>是否相同

是否有可能找出两个expression式是否相同?

像给出以下四个expression式:

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; 

那么,至less我们可以看到:

  • a == b
  • a != c
  • a != d

但是,我可以做任何事情在我的代码中find这个吗?

看了msdn库,在那里说

Equals :确定指定的对象是否等于当前的Object 。 (从Objectinheritance。)

我猜这意味着至lessexpression式类没有重写equals方法成为Equatable? 那么你会如何做到这一点? 还是我在这里问太多? :p

你可以看看在Linq到db4o中使用的ExpressionEqualityComparertypes。 它实现了接口IEqualityComparer <T>,所以它可以用于generics集合,也可以用于独立使用。

它使用ExpressionComparisontypes来比较两个expression式的相等性,并使用HashCodeCalculation从expression式计算哈希码。

这一切都涉及到访问expression式树,所以如果你反复做这件事可能会相当昂贵,但也可以非常方便。

该代码可以在GPL或dOCL下获得

例如,这是你的testing:

 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)); } } 

它确实印出真,假,假。

作为一个懒惰的回答,你可以检查ToString() – 它至less应该指明它们在哪里明显不同(尽pipe它将包含var-name,所以必须是相同的)。

为了准确地检查等价性,要花费很多的工作量,在许多不同的节点types上。

除了最简单的情况之外,我觉得这可能很难做到。

例如:

 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; 

从技术上讲,这些都是平等的,但是如何在不评估每个expression式返回的IEnuemrable的情况下如何确定呢?