51

2 つの式が同じかどうかを調べることはできますか?

次の 4 つの式が与えられた場合のように:

        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;

次に、少なくとも次のことがわかります。

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

しかし、コードでこれを見つけるために何かできるでしょうか?

msdn ライブラリをのぞいてみると、次のように書かれています。

Equals: 指定された Object が現在の と等しいかどうかを判断しますObject。(から継承Object。)

これは、少なくとも Expression クラスが equals メソッドをオーバーライドして Equatable になっていないことを意味していると思いますか? それで、あなたはこれをどのようにしますか?それとも、私はここであまりにも多くを求めていますか? :p

4

3 に答える 3

38

Linqtodb4o内で使用されるExpressionEqualityComparer型を確認できます。インターフェースIEqualityComparer<T>を実装しているため、ジェネリックコレクションだけでなく、スタンドアロンでの使用にも使用できます。

Comparison型を使用して2つの式が等しいかどうかを比較し、HashCodeCalculationを使用して式からハッシュコードを計算します。

すべて式ツリーにアクセスする必要があるため、繰り返し実行するとかなりコストがかかる可能性がありますが、非常に便利な場合もあります。

コードはGPLまたはdOCLで入手できます

たとえば、これがあなたのテストです:

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

そしてそれは確かにTrue、False、Falseを出力します。

于 2009-03-23T12:44:49.117 に答える
20

怠惰な答えとして、チェックすることができますToString()-少なくともそれらが明らかに異なる場所を示す必要があります(ただし、そこにはvar-nameが含まれるため、同じである必要があります)。

同等性を正確にチェックするために...はるかに困難です-多くの異なるノードタイプにわたって、多くの作業が必要です。

于 2009-03-23T12:50:19.663 に答える
4

最も単純な場合を除いて、これを行うのは難しいかもしれないと思います。

例えば:

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;

技術的には、これらは等しいですが、各式で返される IEnuemrable を評価せずにどのように判断できるのでしょうか?

于 2009-03-23T12:38:05.357 に答える