Quelle est la meilleure stratégie pour d'égal à Égal et GetHashCode?
Je travaille avec un modèle de domaine et a la réflexion sur les différentes façons que nous avons de mettre en œuvre ces deux méthodes .NET. Quelle est votre stratégie préférée?
C'est mon actuel de mise en œuvre:
public override bool Equals(object obj)
{
var newObj = obj as MyClass;
if (null != newObj)
{
return this.GetHashCode() == newObj.GetHashCode();
}
else
{
return base.Equals(obj);
}
}
//Since this is an entity I can use its Id
//When I don't have an Id, I usually make a composite key of the properties
public override int GetHashCode()
{
return String.Format("MyClass{0}", this.Id.ToString()).GetHashCode();
}
- Connexes: stackoverflow.com/questions/2326288/...
- Vous ne pouvez pas utiliser les résultats de GetHashCode comme le seul facteur déterminant dans votre Égalité des codes de hachage peut être la même lorsque les objets sont différents. Vous feriez beaucoup mieux de la comparaison de votre Id d'égal à Égal. Pour plus de détails, voir Pourquoi est-il important de remplacer GetHashCode lorsque la méthode Equals est surchargé en C#?
- Vous devez garder à l'esprit que GetHashCode() est principalement utilisé dans le code où la performance est importante (listes de O(1) recherches, etc.). Votre application est déjà assez lent, mais vous pouvez accélérer déjà sans modifier la quantité:
return ("MyClass" + this.Id).GetHashCode();
(juste quelque chose que vous voudrez peut-être garder à l'esprit avec GetHashCode) - double possible de Quel est le meilleur algorithme pour un substituée Système.Objet.GetHashCode?
- En fondant hachages sur une chaîne concaténée à tous est probablement une mauvaise idée.
Vous devez vous connecter pour publier un commentaire.
En supposant que les instances sont égaux parce que les codes de hachage sont l'égalité est fausse.
Je suppose que votre mise en œuvre de GetHashCode est OK, mais j'ai l'habitude d'utiliser les choses de similaire à ceci:
Domain-Driven Design fait la distinction entre Entités et des Objets de Valeur de. C'est une bonne distinction à observer, car il guide la façon dont vous implémenter Equals.
Entités sont égales si leurs codes d'identification de l'égalité de l'autre.
Des Objets de valeur de sont égaux si leurs (important) les éléments constitutifs sont égaux les uns aux autres.
Dans tous les cas, la mise en œuvre de GetHashCode devrait se baser sur les mêmes valeurs qui sont utilisées pour déterminer l'égalité. En d'autres termes, pour les Entités, le code de hachage doit être calculé directement à partir de l'ID, alors que pour les Objets de Valeur, il doit être calculé à partir de tous les constituants des valeurs.
Equals()
méthode sur Entités qui compare les Identifiants? Quels sont les cas d'utilisation? J'ai demandé à une question similaire ici sur SO, mais jusqu'à maintenant, je n'ai pas eu une réponse qui indique clairement pourquoi les entités doivent être comparés en fonction de leur ID.Aucune des réponses ici vraiment frappé la tache pour moi. Puisque vous avez déjà dit que vous ne pouvez pas utiliser
Id
pour l'égalité, et vous avez besoin d'utiliser un faisceau de propriétés, voici une meilleure façon de le faire. Note: je ne considère pas cet être la meilleure façon de mettre en œuvreEquals
etGetHashCode
. C'est une meilleure version de l'OP du code.Voir cette réponse de Jon Skeet pour une partie du raisonnement derrière cela. À l'aide de xor n'est pas bon parce que les divers ensembles de données peuvent résultant dans le même hash. Cette synthèse autour de la méthode avec les nombres premiers (les valeurs de départ de 19 et 31 ci-dessus, ou d'autres valeurs que vous choisissez) fait un meilleur travail de la segmentation dans des "compartiments" qui ont peu de collisions chaque.
Si l'un de vos valeurs peuvent être nulles, je vous encourage à réfléchir attentivement à la manière dont ils devraient comparer. Vous pouvez utiliser le court-circuit null évaluation et le nul de la coalescence de l'opérateur, peut-être. Mais assurez-vous que si les valeurs null doit comparer que l'égalité que vous attribuer des codes de hachage pour les différents nullable propriétés lorsqu'ils sont nuls.
Aussi, je ne suis pas convaincu que votre
Equals
mise en œuvre de sens. Lorsque deux objets sont comparés pour l'égalité, le premier leurGetHashCode
valeurs sont comparées. Seulement si ceux-ci sont différents, c'est leEquals
méthode run (de sorte que si deux objets de hachage à la même valeur sont différents, cela sera détecté). Depuis votreGetHashCode
mise en œuvre ne fait pas référence à labase
, il peut n'avoir aucun sens pour votreEquals
méthode pour le faire. Plus précisément, vous aurez un sérieux problème d'attente de casser des choses siEquals
peut retourner true pour deux objets dont les codes de hachage sont différents.Hashcodes peuvent entrer en collision, donc je ne pense pas qu'ils sont une bonne façon de comparer les sexes. Nous vous conseillons de comparer les valeurs sous-jacentes qui font les objets de "l'égalité" à la place. Voir @Jon Skeet, la réponse à cette question: Quel est le meilleur algorithme pour un substituée Système.Objet.GetHashCode? pour une meilleure GetHashCode mise en œuvre si votre égalité englobe plusieurs propriétés. Si c'est juste une seule propriété, vous pouvez réutiliser c'est hashcode.
Je suis tombé sur cette vieille question et, à mon humble avis, je n'ai pas trouvé de réponse claire et simple énoncé de la question initiale formulée par @tucaz.
Je suis d'accord avec beaucoup de considérations partagé ci-dessus (ou en dessous :D), mais «la Question du point» a été raté (je pense).
À condition que:
Je peux deviner qu'une simple mise en œuvre pourrait être:
C'est tout!