如何检查两个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
。 (从Object
inheritance。)
我猜这意味着至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的情况下如何确定呢?