web-dev-qa-db-ja.com

2つのExpression <Func <T、bool >>が同じかどうかを確認する方法

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;

次に、少なくともweは次のことを確認できます。

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

しかし、コードでこれを見つけるために何かできることはありますか?

Msdnライブラリを覗いてみたところ、

Equals:指定されたオブジェクトが現在のObjectと等しいかどうかを判別します。 (Objectから継承されます。)

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

44
Svish

Linq to db4o 内で使用されるタイプ ExpressionEqualityComparer を見ることができます。インターフェースIEqualityComparer <T>を実装しているため、汎用コレクションだけでなく、スタンドアロンでの使用にも使用できます。

タイプ ExpressionComparison を使用して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を出力します。

35
Jb Evain

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

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

17
Marc Gravell

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

例えば:

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を評価せずにどのように決定できますか?

4
Dustin Campbell