【问题标题】:Have to manually implement IEquatable<T> but not IComparable<T>? [duplicate]必须手动实现 IEquatable<T> 而不是 IComparable<T>? [复制]
【发布时间】:2021-02-23 01:57:34
【问题描述】:

我做了一个自定义的通用列表类:

class ComparableList<T> : IList<T>  where T : IComparable<T>

对于泛型类型,我可以使用直接实现 IComparable 的类型,例如:

class MyComparableClass : IComparable<MyComparableClass>

或者我可以使用继承自它的类型:

class MyInheritedClass : MyComparableClass

然后我决定IEquatable&lt;T&gt;会更适合。

所以我改变了列表类的约束,让MyComparableClass同时实现IComparable&lt;MyComparableClass&gt;IEquatable&lt;MyComparableClass&gt;

由于某种原因,我不能再将MyInheritedClass 用作自定义列表的泛型类型,除非我手动使其实现IEquatable&lt;MyInheritedClass&gt;。我将列表约束切换回IComparable&lt;T&gt;,突然之间我可以再次使用继承的类。

IComparable&lt;T&gt;IEquatable&lt;T&gt; 之间有什么不同导致规则不同?

【问题讨论】:

  • 如果你实现IList&lt;T&gt;,你可能也应该实现IReadOnlyList&lt;T&gt;(这是因为IList&lt;T&gt;由于历史原因没有扩展IReadOnlyList&lt;T&gt; - 这将被修复最终 但不要指望至少再过几年)。

标签: c# .net


【解决方案1】:

您的问题有点杂乱且难以理解,但如果我们只关注最后两段:

由于某种原因,我不能再将 MyInheritedClass 用作自定义列表的泛型类型,除非我手动使其实现 IEquatable。我将列表约束切换回 IComparable 并且突然之间我可以再次使用继承的类。

IComparable 和 IEquatable 之间有什么不同导致规则不同?

协方差。 IComparable&lt;T&gt; 如您所写,实际上定义为 IComparable&lt;in T&gt;,而 IEquatable&lt;T&gt; 就是这样。

这是有道理的,因为相等性是一个非常强的陈述,所以它的接口只接受与您正在测试的对象类型相同的对象类型(即没有协方差),而您可以将苹果与橙子进行比较,如果您所以希望,例如,一个比另一个更橙色,因此在这种情况下具有协变可比接口是有意义的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    • 1970-01-01
    相关资源
    最近更新 更多