为什么IEquatable T在T#4.0中没有逆变?

时间:2010-07-20 11:31:23

标签: c# c#-4.0

IEquatable< T>因为它仅在输入位置使用T(或者,等效地,U是T的子类型,应该暗示IEquatable< T>是IEquatable< U>的子类型)。可以在T中声明是逆变的。 / p>

那么,为什么BCL团队没有使用'in'关键字对它进行注释(对于C#4.0),就像他们使用许多其他通用接口(如完全类似的IComparable)那样?

2 个答案:

答案 0 :(得分:13)

我认为这主要是出于哲学原因而非技术限制 - 因为简单地注释界面是完全可能的。 IEquatable<T>用于比较相同类型的对象以获得完全相等。通常认为超类的实例等于子类的实例。在这个意义上的平等也意味着类型平等。这与IComparable<in T>略有不同。在不同类型中定义相对排序顺序是明智的。

引用MSDN page on IEquatable<T>

  

对实施者的说明:

     

IEquatable<T>界面的type参数替换为实现此界面的类型

这句话进一步说明了IEquatable<T>意味着在单个具体类型的实例之间工作的事实。

答案 1 :(得分:1)

可继承类型通常不应实现IEquatable<T>。如果IEquatable<T>包含GetHashCode()方法,则可以定义IEquatable<T>的语义,以便在检查为T时项目应该相等。不幸的是,IEquatable<T>绑定到与Object.Equals相同的哈希码这一事实意味着通常IEquatable<T>必须实现与Object.Equals基本相同的语义。

因此,如果IEquatable<BaseClass>的实现除了在其中调用Object.Equals之外执行任何操作,则派生类将覆盖Object.EqualsGetHashCode()并且不会重新实现{ {1}}将最终破坏该接口的实现;简单地调用IEquatable<BaseClass>的{​​{1}}的实现即使在那种情况下也能正常工作,但与没有实现IEquatable<BaseClass>的类相比,它没有真正的优势。

鉴于可继承类不应该首先实现Object.Equals,协方差的概念与接口的正确实现无关。