J'implémente un DoubleEqualityComparer réutilisable (avec une tolérance personnalisée: le paramètre constructeur "epsilon") pour faciliter l'utilisation de LINQ avec des séquences de double. Par exemple:IEqualityComparer <double> avec une tolérance; comment implémenter GetHashCode?
bool myDoubleFound = doubles.Contains(myDouble, new DoubleEqualityComparer(epsilon: 0.01));
Quelle est la bonne façon d'implémenter GetHashCode? Voici le code:
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: Je peux toujours retourner la même valeur (ex: GetHashCode (Double obj) {return 0;}) pour forcer toujours l'appel à Equals méthode (à double, double) (pas très performant, je sais), mais je me souviens que cette solution cause des problèmes quand le comparateur est utilisé avec un dictionnaire ...
Vous ne devriez pas faire cela parce que cela viole la transitivité. Il est possible que 'a est égal à b' et' b 'est égal à c' mais 'a not n'est pas égal à c'. – Ani