C# 如何检查两个 Expression<Func<T, bool>> 是否相同
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/673205/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check if two Expression<Func<T, bool>> are the same
提问by Svish
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 wecan see that:
那么,至少我们可以看到:
a == b
a != c
a != d
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
看了一下 msdn 库,它说
Equals
: Determines whether the specified Object is equal to the currentObject
. (Inherited fromObject
.)
Equals
: 判断指定的 Object 是否等于当前的Object
。(继承自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
我猜这意味着至少 Expression 类没有覆盖 equals 方法成为 Equatable?那么你会怎么做呢?还是我在这里问的太多了?:p
采纳答案by Jb Evain
You can have a look at the type ExpressionEqualityComparerthat 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.
您可以查看在Linq to db4o 中使用的ExpressionEqualityComparer类型。它实现了接口 IEqualityComparer<T>,因此它可用于泛型集合,也可用于独立使用。
It uses the type ExpressionComparisonto compare two Expressions for equality, and HashCodeCalculation, to compute a hashcode from an Expression.
它使用类型ExpressionComparison来比较两个表达式的相等性,并使用HashCodeCalculation来根据表达式计算哈希码。
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
该代码在 GPL 或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.
它确实打印了 True, False, False。
回答by Dustin Campbell
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?
从技术上讲,这些是相等的,但是如何在不评估每个表达式中返回的 IEnuemrable 的情况下确定它?
回答by Marc Gravell
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).
作为一个懒惰的答案,您可以检查ToString()
- 它至少应该指出它们明显不同的地方(尽管它会在其中包含 var-name,因此必须相同)。
For checking equivalence accurately... much harder - a lot of work, over a lot of different node types.
为了准确地检查等效性......要困难得多 - 大量工作,在许多不同的节点类型上。