Dot-Net
帶有容差的 IEqualityComparer<double>;如何實現GetHashCode?
我正在實現一個可重用的 DoubleEqualityComparer(具有自定義容差:“epsilon”建構子參數)以簡化 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) 方法(我知道不是很高效),但我記得這個當比較器與字典一起使用時,解決方案會導致問題……
我不確定使用
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)); }
我會投
NotSupportedException進去,GetHashCode這樣你就可以吃蛋糕了。這為您提供了使用IEqualityComparerin LINQ 和其他方法的便利,但保證了任何使用都會GetHashCode崩潰。在實踐中,您可能會發現使用相等比較器的方式實際上不需要GetHashCode呼叫。你甚至可以呼叫這個類NotHashableDoubleEqualityComparer來非常清楚對呼叫者的限制。