2009-01-04 11 views
50

Si je veux comparer des objets et ils mettent en œuvre la IEquatable <> interface, j'ai quelques questions:Comprendre IEquatable

  1. Pourquoi dois-je passer outre equals (Object) si je dois implementer equals <>
  2. puis-je utiliser == et! = Une fois que j'implémente IEquatable?

Répondre

50

En ce qui concerne # 1:

De 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 est compatible avec celui de la méthode IEquatable<T>::Equals . Si vous faites passer outre Object::Equals(Object), votre implémentation surchargée est également appelé dans les appels à la méthode Equals(System.Object, System.Object) statique de votre classe. Cela garantit que toutes les invocations de la méthode Equals() renvoient des résultats cohérents.

2) Non, ils effectuent des comparaisons de références simples et n'utilisent pas la méthode Equals.

+0

Ainsi, lorsque vous traitez avec des objets, == supposé ne signifier que la même adresse mémoire exacte (même instance) – leora

+0

Assez. Plus d'informations ici: http://msdn.microsoft.com/en-us/library/53k8ybth(VS.80).aspx –

+6

Non, utilisez ReferenceEquals() à cet effet. L'opérateur d'égalité (==) signifie généralement la même chose, mais peut être surchargé (par exemple pour Strings et similaires). –

39

1) Comme l'a dit Ray, remplacez Equals(object) pour assurer la cohérence lorsque la méthode est appelée à partir de classes qui ne savent pas (statiquement) que vous implémentez IEquatable<T>. Par exemple, les classes de collections non génériques utiliseront Equals(object) pour les comparaisons. Vous devez également remplacer GetHashCode().

2) L'implémentation IEquatable<T> ne surcharge pas les opérateurs == et! = Automatiquement, mais rien ne vous empêche de le faire, tout comme le fait System.String. Vous devez documenter cela très clairement si vous faites, cependant - et soyez prudent lorsque vous faites des comparaisons entre d'autres types de référence (par exemple MyType et Object) qui utilisera toujours la comparaison d'identité. Je pense que ce n'est pas une bonne idée de le faire à moins que ce soit un type très utilisé dans votre code, où tout le monde connaîtra très bien et où le sucre syntaxique de surcharge == aura vraiment un impact positif sur lisibilité.

+0

Jon, y a-t-il un gain de performance pour un type d'implémentation IEquatable utilisé par exemple dans une Collection , appelant la méthode Contient? – Rauhotz

+6

Il va éviter de lancer, oui. Pour les types de valeur, cela évitera la boxe et le déballage. Voir les documents pour Collection .Contains - il utilise EqualityComparer .Default, qui utilisera l'implémentation IEquatable si possible. –

+5

Oui, ce n'est pas une bonne idée de surcharger l'opérateur == et! = Pour fournir des vérifications d'égalité de valeur (par rapport à la vérification d'égalité de référence par défaut). La documentation MSDN suggère que vous le faites uniquement pour les types immuables. Il existe également des problèmes liés aux interfaces et à la surcharge de l'opérateur. –