Question

Quelle est la meilleure façon de créer votre propre méthode GetHashCode pour une classe en C #? Supposons que j'ai une classe simple (qui remplace la méthode equals), comme suit:

class Test
{
   public string[] names;

   public double[] values;

   public override bool Equals(object obj)
   {
      return (obj is Test) && this.Equals((Test)obj);
   }

   public bool Equals(Test t)
   {
      return names.Equals(t.names) && values.Equals(t.values);
   }
}

Dois-je utiliser le code par défaut pour la méthode GetHashCode?

public override int GetHashCode()
{
   return base.GetHashCode();
}

La base doit I la méthode sur le contenu de ma classe?

public override int GetHashCode()
{
   return names.GetHashCode() + values.GetHashCode() ;
}

Ou dois-je faire autre chose?

Était-ce utile?

La solution

System.Array ne remplace pas GetHashCode ou Equals, ils utilisent l'égalité de référence. Par conséquent, vous ne devriez pas les appeler.

Pour mettre en œuvre GetHashCode, voir cette question .

Pour mettre en œuvre Equals, utilisez le SequenceEqual méthode d'extension.

EDIT : .Net 2.0, vous devez écrire votre propre version de SequenceEqual, comme ceci:

public static bool SequenceEquals<T>(IList<T> first, IList<T> second) {
    if (first == second) return true;
    if (first == null || second == null) return false;

    if (first.Count != second.Count) return false;

    for (int i = 0; i < first.Count; i++)
        if (!first[i].Equals(second[i]))
            return false;

    return true;
}

Vous pouvez écrire à prendre IEnumerable<T> au lieu de IList<T>, mais ce serait un peu plus lent, car il ne serait pas en mesure de sortir tôt si les paramètres ont des tailles différentes.

Autres conseils

Il est vraiment important de vous assurer que vous gardez le remplacement des .GetHashCode () à l'étape avec Equals ().

En gros, vous devez vous assurer qu'ils considèrent les mêmes domaines afin de ne pas violer le premier des trois règles de GetHashCode ( MSDN Object.GetHashCode () )

  

Si deux objets se comparent comme égales par ailleurs,   Procédé GetHashCode pour chaque objet   doit retourner la même valeur. cependant,   si deux objets ne se comparent pas   égales, les méthodes de GetHashCode pour la   deux objets ne pas revenir   des valeurs différentes.

En d'autres termes, vous devez vous assurer que tous les Equals temps considère deux cas égaux, ils auront également la même .GetHashCode ().

Comme mentionné par quelqu'un d'autre ici, cette question détails une bonne mise en œuvre. Si vous êtes intéressé, j'ai écrit quelques articles de blog sur l'étude des codes de hachage début de l'année dernière. Vous pouvez trouver mes divagations (la première entrée de blog je l'ai écrit sur le sujet)

Il y a une bonne discussion sur les questions BaseObject classe abstraite fournie par SharpArchitecture.

Si vous voulez quelque chose de plus ad hoc , j'ai trouvé que le code qui génère ReSharper pour equals () et GetHashCode () est très bien.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top