Estoy implementando un DoubleEqualityComparer reutilizable (con una tolerancia personalizada: el parámetro constructor "epsilon") para facilitar el uso de LINQ con secuencias de doble. Por ejemplo:IEqualityComparer <double> con una tolerancia; cómo implementar GetHashCode?
bool myDoubleFound = doubles.Contains(myDouble, new DoubleEqualityComparer(epsilon: 0.01));
¿Cuál es la forma correcta de implementar GetHashCode? Aquí está el código:
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)
{
// ?
}
}
PD: siempre puede volver el mismo valor (por ejemplo: GetHashCode (doble obj) {return 0;}) para forzar siempre la llamada al método equals (doble, doble) (no muy rendimiento, lo sé), pero recuerdo que esta solución causa problemas cuando el comparador se utiliza con un diccionario ...
No debe hacer esto porque viola la transitividad. Es posible que 'a sea igual a b' y' b sea igual a c' pero 'a no sea igual a c'. – Ani