2012-06-29 13 views
5

私は再利用可能なDoubleEqualityComparer(カスタム許容値: "ε"コンストラクタパラメータ)を実装して、LINQの使用を簡単にして、doubleのシーケンスで実装しています。例:IEqualityComparer <double>には許容値があります。どのようにGetHashCodeを実装するのですか?

bool myDoubleFound = doubles.Contains(myDouble, new DoubleEqualityComparer(epsilon: 0.01)); 

GetHashCodeを実装する正しい方法は何ですか?ここでは、コードは次のとおり

public class DoubleEqualityComparer : IEqualityComparer<double>, IEqualityComparer<double?> 
    { 
     private readonly double epsilon; 

     public DoubleEqualityComparer(double epsilon) 
     { 
      if (epsilon < 0) 
      { 
       throw new ArgumentException("epsilon can't be negative", "epsilon"); 
      } 

      this.epsilon = epsilon; 
     } 

     public bool Equals(double x, double y) 
     { 
      return System.Math.Abs(x - y) < this.epsilon; 
     } 

     public int GetHashCode(double obj) 
     { 
      // ? 
     } 
    } 

PS:私は常に同じ値を返すことができる(例:GetHashCodeメソッド(ダブルOBJ){戻り0;})は、常に等号のコール(二重、二重)を強制する方法(あまり私は知っている)、しかし、この解決策は、コンペアが辞書で使われるときに問題を引き起こすことを覚えています...

+8

これは推移性に違反するため、これを行うべきではありません。 'aはbと等しく、bはcと同じですが、aはcと等しくない可能性があります。 – Ani

答えて

4

私はEqualityComparerを使うのはよくわかりません。比較対象は等価ではないためです。あなたがあなたのケーキを持って、あまりにもそれを食べることができますので、私はGetHashCodeNotSupportedExceptionを投げるでしょう

private static bool DoublesAreNearlyEquals(double d1, double d2, double epsilon = 0.01D) 
{ 
    return System.Math.Abs(d1 - d2) < this.epsilon; 
} 

private void foo() 
{ 
    var myDoubles = Getdoubles(); 
    var doubleToSearch = 42D; 
    var result = myDoubles.Any(d=>DoublesAreNearlyEquals(d, doubleToSearch)); 
} 
+1

おかげで、あなたとアニは、カスタムインターフェース(および拡張メソッドのセット、LINQスタイル)を定義したIEqualityComparerを使用しないように私を確信し、しかし: パブリックインターフェイスITolerable { ブールAreAlmostEqual(TのX、T yを) ; } IEqualityComparerは、(GetHashcodeを呼び出さない)LINQの公式メソッドが用意されているので便利ですが、実装されていないまま残すためにundestandはひどい(危険です)。 – Notoriousxl

1

たぶん、あなたは、単純なAny句+ユーティリティメソッドを使用して検討すべきです。これにより、IEqualityComparerをLINQやその他の方法で使用する際の利便性が向上しますが、GetHashCodeの使用が爆発的に増加することが保証されます。実際には、等価比較者を使用する方法では実際にGetHashCodeが呼び出されることはありません。このクラスNotHashableDoubleEqualityComparerを呼び出して、発信者の制限について明確にすることさえできます。

関連する問題