在大多数地方,我读到一个好主意,即从您的类中的IComparable
和IComparable<T>
继承,以提供与非通用集合的兼容性。我的问题是,为什么默认情况下IComparable<T>
不继承自IComparable
?向后兼容性将通过这种方式实现。
例如,IEnumerable<T>
确实继承了IEnumerable
,那么为什么不对IComparable
做同样的事情?我读到了有关差异的信息,但我仍然不太明白为什么要这样设计。我试图用一个具有相同体系结构的接口创建一个小示例,它可以按预期工作。
编辑:
此外,Microsoft文档指出以下内容:
如果通用接口是反变的,则通用接口可以从非通用接口继承,这意味着它仅将其type参数用作返回值。在.NET Framework类库中,IEnumerable<T>
继承自IEnumerable
,因为IEnumerable<T>
仅在返回值GetEnumerator
和属性Current
中使用T。
但是,尽管如此,您仍然可以从IComparable
继承IComparable<T>
(如果您创建具有相同架构的接口,就是这样)。
答案 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(它的前通用对等物)退出发行的不错选择。