开发者

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开发者_如何学JAVA 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜