11

再利用可能なDoubleEqualityComparer(カスタム許容値:「epsilon」コンストラクターパラメーターを使用)を実装して、doubleのシーケンスでのLINQの使用を容易にします。例えば:

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(double obj){return 0;})常にEquals(double、double)メソッドの呼び出しを強制します(あまりパフォーマンスが良くない、私は知っています)が、これを覚えています比較器を辞書で使用すると、解決策によって問題が発生します。

4

2 に答える 2

6

使用する方法がわかりませんIEqualityComparer<T>。比較されたオブジェクトは等しくないからです。

たぶん、単純なAny句とユーティリティメソッドの使用を検討する必要があります。

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));
}
于 2012-06-29T09:26:02.493 に答える
2

NotSupportedException私はあなたがあなたのケーキを持ってそれを食べることができるように投げGetHashCodeます。IEqualityComparerこれにより、LINQやその他のメソッドを使用できるという便利さが得られますが、使用法がGetHashCode爆発することが保証されます。実際には、等式比較器を使用する方法を実際GetHashCodeに呼び出す必要がないことに気付くかもしれません。NotHashableDoubleEqualityComparer発信者への制限について非常に明確にするために、このクラスを呼び出すこともできます。

于 2016-06-03T15:49:20.970 に答える