为什么IEquatable T在T#4.0中没有逆变?
IEquatable 可能已被声明为T中的逆变,因为它仅在输入位置使用T(或者,等效地,U是T的子类型应该暗示IEquatable 是[IE的一个子类] IEquatable )。
那么,为什么BCL团队没有使用’in’关键字对它进行注释(对于C#4.0),因为它们与许多其他通用接口(如完全类似的IComparable)一样?
我认为这主要是出于哲学原因而不是技术限制 – 因为简单地注释界面是完全可能的。 IEquatable
旨在比较相同类型的对象以获得完全相等。 通常认为超类的实例等于子类的实例。 在这个意义上的平等也意味着类型平等。 这与IComparable
略有不同。 在不同类型中定义相对排序顺序是明智的。
在IEquatable
上引用MSDN页面 :
对实施者的说明:
将
IEquatable
接口的type参数替换为实现此接口的类型 。
这句话进一步说明了IEquatable
旨在在单个具体类型的实例之间工作的事实。
可inheritance类型通常不应该实现IEquatable
。 如果IEquatable
包含一个GetHashCode()
方法,那么可以定义IEquatable
的语义, IEquatable
在检查为T时,项目应该比较相等。 不幸的是, IEquatable
绑定到与Object.Equals
相同的哈希码这一事实意味着IEquatable
通常必须实现与Object.Equals
基本相同的语义。
因此,如果IEquatable
实现除了在其中调用Object.Equals
之外还执行任何操作,则重写Object.Equals
和GetHashCode()
并且不重新实现IEquatable
的派生类将最终导致实现中断那个界面; 简单地调用Object.Equals
的IEquatable
的实现即使在那种情况下也能正常工作,但与没有实现IEquatable
的类相比,它没有真正的优势。
鉴于可inheritance类不应该首先实现IEquatable
,协方差的概念与接口的正确实现无关。