简体   繁体   中英

Why was IEquatable T not made contravariant in T for C# 4.0?

IEquatable<T> could have been declared to be contravariant in T, since it only uses T in an input position (or, equivalently, U being a subtype of T should imply that IEquatable<T> is [a subtype of] IEquatable<U>).

So, why did the BCL team not annotate it (for C# 4.0) with the 'in' keyword, as they did with many other generic interfaces (like the entirely analogous IComparable)?

I think this is mainly for a philosophical reason rather than a technical limitation–as it's perfectly possible to simply annotate the interface. IEquatable<T> is meant to compare objects of the same type for exact equality. An instance of a superclass is not usually considered equal to an instance of a subclass. Equality in this sense implies type equality too. This is a bit different from IComparable<in T> . It can be sensible to define a relative sort order across different types.

To quote MSDN page on IEquatable<T> :

Notes to Implementers:

Replace the type parameter of the IEquatable<T> interface with the type that is implementing this interface .

This sentence further demonstrates the fact that IEquatable<T> is meant to work between instances of a single concrete type.

Inheritable types should generally not implement IEquatable<T> . If IEquatable<T> included a GetHashCode() method, one could define the semantics of IEquatable<T> to say that items should compare equal when examined as T's. Unfortunately, the fact that IEquatable<T> is bound to the same hash code as Object.Equals means that in general IEquatable<T> has to implement essentially the same semantics as Object.Equals .

Consequently, if an implementation of IEquatable<BaseClass> does anything other than call Object.Equals within it, a derived class which overrides Object.Equals and GetHashCode() and does not re-implement IEquatable<BaseClass> will end up with a broken implementation of that interface; an implementation of IEquatable<BaseClass> which simply calls Object.Equals will work just fine, even in that scenario, but will offer no real advantage over a class which doesn't implement IEquatable<T> .

Given that inheritable classes shouldn't be implementing IEquatable<T> in the first place, the notion of covariance is not relevant to proper implementations of the interface.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM