为什么IComparable<T>没有继承自IComparable接口?

5
在大多数地方我看到建议在你的类中从IComparableIComparable<T>继承,以提供与非泛型集合的兼容性。我的问题是为什么IComparable<T>默认情况下没有继承IComparable呢?这样可以实现向后兼容。例如,IEnumerable<T>确实继承自IEnumerable,那么为什么不对IComparable做同样的事情呢?我读到了一些关于变异的文章,但我仍然不太明白为什么要设计成这样。我尝试创建一个带有相同架构的接口小例子,它可以按预期工作。
编辑:此外,微软文档声明如下: 如果泛型接口只将其类型参数用作返回值,则泛型接口可以从非泛型接口继承。在.NET Framework类库中,因为IEnumerable<T>只在GetEnumerator的返回值和Current属性的getter中使用T,所以IEnumerable<T>继承自IEnumerable
但尽管如此,人们可以很好地从IComparable<T>继承IComparable(如果创建具有相同架构的接口)。

可能会给你一个想法。 (并且它不适用于IEnumerable。) - GSerg
我看到了那个问题,当我试图查找我的问题时。虽然它只是描述了一个同时实现两个接口的类的可能实现方式。我的问题是为什么IComparable<T>一开始就没有继承自IComparable - Andrew Petukhov
这个问题只能由语言的设计者回答。其他答案都将是猜测和推测。例如,参见 Meta 问题 如果它可以有官方答案,那么询问语言规范“为什么”仍被认为是“主观性意见为主”的吗? - Heretic Monkey
2个回答

0

这归结于语言设计决策,所以除了开发人员的消息,我们只能猜测。

一个很好的原因是其中一个是通用的,而另一个不是。与非通用解决方案(使用对象作为类型)相比,泛型本质上优于非泛型解决方案,因为它们在编译时保持类型安全。因此,可能有一个故意的选择来打破前泛型版本。为了避免向下兼容性。请注意,实现Generic版本的大多数类都不实现其非泛型对应项。像字符串这样的真正基础和古老的东西是例外-因为他们无法删除旧接口,只能添加新接口。

对于枚举器,需要似乎不是很极端。枚举器通常是从集合中生成或生成的,仅供阅读处理。因此,您可以将其固定类型进行转换或在枚举器中使用固定类型。

另一个原因可能是使用IComparable的代码或明确要求它(类型约束),或者由它制作的内容--并且从定义上就是泛型的。最常用于泛型集合中的排序函数。他们可能不想再使用旧的集合了。而不支持字典上的IComparable肯定是一个不错的选择,以使HashTable(它的前泛型对应项)停止使用。


0

如果未指定类型,则实现通用接口的类也需要实现默认类型方法。请自行尝试。

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

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

会变成

public class Foo : IFoo<int>
    {
        void IFoo<int>.Foo(int o)
        {
            throw new System.NotImplementedException();
        }

        void IFoo.Foo(object o)
        {
            throw new System.NotImplementedException();
        }
    }

在这种情况下,您实现了一个带有一个方法的接口,但似乎必须从类型化接口继承两个方法。

因此,主要问题在于使用这种继承方式时,你不会明显地意识到应该实现两种方法而不仅仅是一种方法。 - Andrew Petukhov
Foo类继承自IFoo<object>接口,怎么样? - user11523568

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接