为什么IComparable <T>不继承自IComparable?

时间:2019-09-23 14:59:48

标签: c# interface comparable contravariance icomparable

在大多数地方,我读到一个好主意,即从您的类中的IComparableIComparable<T>继承,以提供与非通用集合的兼容性。我的问题是,为什么默认情况下IComparable<T>不继承自IComparable?向后兼容性将通过这种方式实现。

例如,IEnumerable<T>确实继承了IEnumerable,那么为什么不对IComparable做同样的事情?我读到了有关差异的信息,但我仍然不太明白为什么要这样设计。我试图用一个具有相同体系结构的接口创建一个小示例,它可以按预期工作。

编辑: 此外,Microsoft文档指出以下内容: 如果通用接口是反变的,则通用接口可以从非通用接口继承,这意味着它仅将其type参数用作返回值。在.NET Framework类库中,IEnumerable<T>继承自IEnumerable,因为IEnumerable<T>仅在返回值GetEnumerator和属性Current中使用T。

但是,尽管如此,您仍然可以从IComparable继承IComparable<T>(如果您创建具有相同架构的接口,就是这样)。

2 个答案:

答案 0 :(得分:0)

如果未指定类型,请尝试一下,然后实现通用接口的类也将需要实现默认的类型方法

br <- c(20, 40, 60, 80, 100, 120, 140, 160, 200, 220)
ggplot(df_CK, aes(ck, stat(density))) +
  geom_histogram(breaks = br) +
  geom_text(
    aes(label = round(stat(count) / sum(stat(count)), 2)), 
    stat = 'bin', vjust = -1, breaks = br
  )

变成

    public interface IFoo
    {
        void Foo(object o);
    }

    public interface IFoo<T> : IFoo
    {
        void Foo(T o);
    }

在这种情况下,您使用一种方法实现一个接口,并且看来您必须实现从继承自类型接口的两个方法

答案 1 :(得分:0)

这取决于语言设计决策,因此我们只能猜测很少的开发人员。

一个很好的理由肯定是一个是通用的,另一个不是。泛型在本质上优于非泛型解决方案(通过使用对象作为类型来实现),因为它们在编译时保持类型安全。因此,可能有一个故意选择来打破通用版本。避免向下兼容。请注意,大多数实现通用版本的类如何不实现非通用版本。真正基本的东西和旧的东西(例如字符串)是例外-因为它们无法删除旧的接口,只能添加新的接口。

对于枚举器,需求似乎没有那么极端。枚举器通常是从集合中生成的,而不是从集合中生成的,并且纯粹是读取处理。因此,您也可以使用固定类型进行强制转换,也可以使用固定类型在Enumerator中使用。

另一个原因可能是使用IComparable的代码明确要求它(类型约束)或由它制成的东西组成-并且根据定义本身就是通用的。通常,它用于通用集合中的排序功能。他们可能不想再使用旧的收藏了。而且不支持在Dictionary上使用IComparable无疑是使HashTable(它的前通用对等物)退出发行的不错选择。