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
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を出力します。
怠惰な答えとして、ToString()
をチェックできます-少なくともそれらが明らかに異なる場所を示す必要があります(ただし、そこにはvar-nameが含まれるため、同じである必要があります)。
同等性を正確にチェックするために...はるかに困難です-多くの異なるノードタイプにわたって、多くの作業が必要です。
最も単純な場合を除いて、これを行うのは難しいかもしれないと私は思います。
例えば:
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を評価せずにどのように決定できますか?