J'ai une classe mutable que j'utilise comme clé d'un dictionnaire générique. Deux clés ne doivent être égales que si leurs références sont égales. D'après ce que j'ai lu, dans ce cas, je n'ai pas besoin de remplacer les égaux, GetHashCode ou implémenter IéqualityComparer. P>
est-ce correct? p>
6 Réponses :
oui. L'opération de comparaison par défaut dans System.Object utilise l'égalité de référence. Si ce comportement est ce que vous voulez, les valeurs par défaut doivent fonctionner correctement. P>
Bien que je m'inquiète du comportement si quelqu'un ajoutait plus tard ces substitutions. Le godet de la haquetable serait calculé par le hachage de l'objet au moment où il a été ajouté. Les appels à contenant () et supprimer () et al échouaient ensuite si l'état (et donc hachage) change.
Oui. C'est toujours un tressant. Le hachage d'éléments nécessite une connaissance préalable des objets en question. Même si vous avez fourni vos propres substitutions, une sous-classe pourrait remplacer la vôtre ...
Sauf si vous les remplacez vous-même, scellez-les et faites appel à votre implémentation de la base.
@Jon: vrai. Sceller les méthodes et forcer votre classe + toutes les sous-classes pour faire référence à l'égalité et aux hachages. Vous mettez une grande restriction sur vos sous-classes, dans ce cas, cependant.
Oui, vous avez raison de faire une comparaison A == (ou des annequales) sur deux objets compare leurs références si aucune autre surcharge n'est spécifiée.
String s = "a"; object test1 = (object)s; object test2 = (object)s; Debug.Assert(test1.Equals(test2));
Vous ne pouvez pas remplacer i> ==, vous ne pouvez que surcharge i> it. De plus, == n'est pas utilisé dans un dictionnaire générique: sont égaux et gethashcode sont.
Oui, c'est correct. tant que vous n'avez pas 'T Remplacer, la référence est la comparaison par défaut. P>
Comme tout le monde a déjà souligné, oui, vous êtes correct. En fait, vous avez définitivement ne voulez pas strong> vouloir remplacer les membres de l'égalité si votre type est mutable (il a des setters). Mais si vous souhaitez avoir une vérification de l'égalité qui utilise des valeurs de votre type, vous pouvez rendre votre type immuable (comme chaîne code>) en veillant à ce qu'il n'y ait pas de seigtisseurs (seuls le constructeur définit les valeurs). Ou utilisez un
struct code>. P>
Je vais ajouter à ce que tout le monde a dit ici (oui) mais avec un point de plus que personne ne semble avoir mentionné ici. P>
Lorsque vous utilisez des collections génériques (dictionnaire, liste, etc.), vous pouvez remplacer IEQUABLE Pour fournir une version spécifique de type pouvant faire votre comparaison sans la boxe ou la coulée de haut en haut. Ces collections génériques utiliseront cette surcharge lorsqu'elles sont présentes pour faire des comparaisons et peuvent être un peu plus efficaces. P>
Comme indiqué dans la DOCS, lors de la mise en œuvre de vous
Je suis content que vous ayez mentionné cela parce que j'avais les mêmes pensées après avoir regardé dans un réflecteur. Ce qui m'a confondu cependant était la nécessité de remplacer GetHashCode même si je ne changerais pas le test d'équivalence. Que voudrai-je remplacer gethashcode?
Pour n'importe qui utilisant .NET 5 ou plus tard, il est livré avec un RéférencesQualityComparer que vous pouvez passer au constructeur du dictionnaire. Cela signifie que vous n'avez pas besoin de vous inquiéter de quelqu'un qui remplace GetHashCode et est égal à l'avenir. P>