Quelle est la différence entre IEquatable et simplement la substitution d’Object.Equals ()?

Je veux que ma classe de Food soit capable de tester chaque fois qu’elle est égale à une autre instance de Food . Je l’utiliserai plus tard contre une liste et je veux utiliser sa méthode List.Contains() . Dois-je implémenter IEquatable ou simplement remplacer Object.Equals() ? De MSDN:

Cette méthode détermine l’égalité en utilisant le comparateur d’égalité par défaut, tel que défini par l’implémentation de l’object de la méthode IEquatable.Equals pour T (le type de valeurs dans la liste).

Ma prochaine question est donc la suivante: quelles fonctions / classes du framework .NET utilisent Object.Equals() ? Devrais-je l’utiliser en premier lieu?

    La principale raison est la performance. Lorsque les génériques ont été introduits dans .NET 2.0, ils ont été en mesure d’append un ensemble de classes telles que List , Dictionary , HashSet , etc. Ces structures utilisent beaucoup GetHashCode et Equals . Mais pour les types de valeur, il fallait une boxe. IEquatable permet à une structure d’implémenter une méthode Equals fortement typée pour qu’aucune boxe ne soit requirejse. Ainsi, de meilleures performances lors de l’utilisation de types de valeur avec des collections génériques.

    Les types de référence n’en profitent pas autant, mais l’ IEquatable vous permet d’éviter une System.Object de System.Object qui peut faire une différence si elle est appelée fréquemment.

    Cependant, comme indiqué sur le blog de Jared Parson , vous devez toujours implémenter les remplacements d’object.

    Selon le MSDN :

    Si vous implémentez IEquatable(T) , vous devez également remplacer les implémentations de classe de base de Object.Equals(Object) et GetHashCode afin que leur comportement soit cohérent avec celui de la IEquatable(T).Equals . Si vous substituez Object.Equals(Object) , votre implémentation remplacée est également appelée dans les appels à la méthode statique Equals(System.Object, System.Object) sur votre classe. Cela garantit que tous les appels de la méthode Equals renvoient des résultats cohérents.

    Il semble donc qu’il n’y ait pas de différence fonctionnelle réelle entre les deux, sauf que l’une peut être appelée en fonction de la manière dont la classe est utilisée. Du sharepoint vue de la performance, il est préférable d’utiliser la version générique car aucune pénalité de boxing / unboxing n’est associée.

    D’un sharepoint vue logique, il est également préférable d’implémenter l’interface. Le remplacement de l’object ne dit pas à personne que votre classe est réellement modifiable. Le remplacement peut simplement être une classe à ne rien faire ou une implémentation superficielle. Utiliser l’interface dit explicitement, “Hey, cette chose est valable pour la vérification d’égalité!” C’est juste un meilleur design.

    Étendre ce que Josh a dit avec un exemple pratique. +1 à Josh – J’étais sur le point d’écrire la même chose dans ma réponse.

     public abstract class EntityBase : IEquatable { public EntityBase() { } #region IEquatable Members public bool Equals(EntityBase other) { //Generic implementation of equality using reflection on derived class instance. return true; } public override bool Equals(object obj) { return this.Equals(obj as EntityBase); } #endregion } public class Author : EntityBase { public Author() { } } public class Book : EntityBase { public Book() { } } 

    De cette façon, j’ai recours à la méthode Equals () réutilisable qui fonctionne parfaitement pour toutes mes classes dérivées.