为什么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.EqualsGetHashCode()并且不重新实现IEquatable的派生类将最终导致实现中断那个界面; 简单地调用Object.EqualsIEquatable的实现即使在那种情况下也能正常工作,但与没有实现IEquatable的类相比,它没有真正的优势。

鉴于可inheritance类不应该首先实现IEquatable ,协方差的概念与接口的正确实现无关。