10
votes

C # Vérification de l'égalité

quelle est votre approche sur l'écriture de vérification de l'égalité des et classes vous créez?

1) La vérification de l'égalité "complète" nécessite une grande partie du code de la chaudière (comme de remplacement correspond à , remplace gethascode , générique Égale , opérateur == , opérateur! = )?

2) Spécifiez-vous explicitement que vos classes modélisent l'interface iéquatif

3) Est-ce que je comprends correctement, qu'il n'y a pas de moyen réel d'appliquer automatiquement égale remplace, lorsque j'invoque quelque chose comme a == B et je dois toujours mettre en œuvre à la fois le égal et opérateur == membres?


0 commentaires

4 Réponses :


1
votes

Vous devez juste avoir besoin d'implémenter l'opérateur == pour A == b. de
Comme j'aime mes données dans des dictionnaires parfois, je remplace GetHashCode.
Suivant I Mettre en œuvre Equals (comme une norme inutilisée ... En effet, il n'ya aucune contrainte pour l'égalité lors de l'utilisation de génériques) et spécifiez la mise en œuvre inégalable. Depuis que je vais faire cela, je pourrais aussi bien pointer mon == et! = Implémentations à égaux. :)


0 commentaires

6
votes

Je fais rarement quelque chose de spécial pour les cours; Pour la plupart des objets réguliers, l'égalité référentielle fonctionne bien.

i encore plus rarement écrire un struct ; Mais puisque les structures représentent les valeurs il est généralement approprié de fournir l'égalité, etc. Cela impliquerait généralement tout; Equals, ==,! = Et Iequatable (car cela évite la boxe dans les scénarios utilisant Equalitalcander .default . .

La chaudière n'est généralement pas trop problématique, mais les outils IIRC comme Restomer peuvent vous aider ici.

Oui, il est conseillé de garder des égaux et == en synchronisation, ce qui doit être fait explicitement.


0 commentaires

20
votes

Vous avez raison, c'est beaucoup de code de plaque de chaudière et vous devez tout implémenter séparément.

Je recommanderais:

  • Si vous allez implémenter une valeur égalité de valeur du tout, remplacez gethashcode et Equals (objet) - Création de surcharges pour == et implémentation iéquatif sans faire cela pourrait entraîner un comportement très inattendu
  • Je voudrais toujours implémenter iéquatif si vous remplissez égale (objet) et gethascode
  • i seulement surchargez l'opérateur == plus rarement
  • La mise en œuvre correctement sur l'égalité des classes non calendrantes est délicate et peut toujours produire des résultats surprenants / indésirables. Si vous avez besoin d'égalité pour types dans une hiérarchie, implémentez IequalityComparer exprimant la comparaison qui vous intéresse.
  • L'égalité des types mutables est généralement une mauvaise idée, car deux objets peuvent être égaux, puis inégal plus tard ... Si un objet est muté (d'une manière égale affectant) après son utilisation comme une clé dans une table de hachage , vous ne pourrez plus le retrouver.
  • Une partie de la plaque de chaudière est légèrement différente pour les structures ... mais comme Marc, j'écris très rarement mes propres structures.

    Voici un exemple de mise en œuvre: xxx

    et oui, c'est un diable de beaucoup de chaudras, dont très peu change entre les implémentations: (

    La mise en oeuvre de == est légèrement moins efficace qu'il pourrait être, car il sera appelé à Equals (objet) Ce qui doit faire la vérification de type dynamique ... mais l'alternative est encore plus une plaque de chaudière, comme ceci: xxx


4 commentaires

2 suggestions mineures pour le deuxième bloc de code: 1) Ne devriez-vous pas déplacer (objet) gauche == (objet) droit à partir de == au générique est égal à < / code>? Donc, cela donne la vitesse (bien sûr cela dépend, mais en supposant le pire des cas) Vérification de l'égalité de référence Même pour Generic Equals Méthode? 2) Vous n'avez pas besoin de la deuxième chèque NULL (objet) droit == null dans == comme vous le faites essentiellement en générique égale . Voir mon post ..


@nawfal: Je ne pense pas qu'il y ait beaucoup de choses à le faire dans le générique égale , il va être rapide de toute façon dans les cas où il est vrai, et pour Les cas où il n'est pas vrai, il s'agit d'un contrôle supplémentaire sans avantage. Quant à la partie null - qui nécessiterait la vérification du type dynamique. Oui, vous pourriez discuter pour les deux - mais je suis assez heureux avec ce que j'ai écrit il y a deux ans ...


@nawfal: Euh, tu as raison - il n'y aurait pas de chèque dynamique là-bas. Je vais supprimer la partie "droite" ici ...


@ Jonskeet, c'est si frustrant d'écrire ce code de la batterie sur et plus lorsque vous faites une erreur est si facile dans ces choses. Heureusement, les extraits peuvent aider à cet égard! J'aurais essayé de m'éloigner en écrivant une classe de base abstrait générique qui fait le travail (je connais les dangers potentiels, mais si je peux gérer, c'est correct) à être dérivé par des classes de base, mais cela limite les classes dérivées de héritage d'une autre classe de base .. juste dire ..



0
votes

voir Quel est le meilleur Pratique "pour comparer deux instances d'un type de référence?

Vous pouvez éviter le code de la plaque de chaudière (l'espoir c # / vs équipe apporte quelque chose de facile pour les développeurs dans leur prochaine itération) avec l'aide d'un extrait d'un extrait, Voici un tel ..


0 commentaires