Sto implementando un DoubleEqualityComparer riutilizzabile (con una tolleranza personalizzata: il parametro del costruttore "epsilon") per facilitare l'utilizzo di LINQ con sequenze di doppio. Ad esempio:IEqualityComparer <double> con tolleranza; come implementare GetHashCode?
bool myDoubleFound = doubles.Contains(myDouble, new DoubleEqualityComparer(epsilon: 0.01));
Qual è il modo corretto per implementare GetHashCode? Ecco il codice:
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: posso sempre tornare lo stesso valore (es: GetHashCode (doppia obj) {return 0;}) per forzare sempre la chiamata al metodo equals (doppio, camera) (non molto performante, lo so), ma ricordo che questa soluzione causa problemi quando il comparatore viene usato con un dizionario ...
Non dovresti farlo perché viola la transitività. È possibile che 'a uguale a b' e' b uguale a c' ma 'a non uguale a c'. – Ani