我想编写一个在类似队列的界面上运行的对象。我去寻找IQueue<T>
,但出乎意料地空手而归。
有以下与集合相关的接口:
ICollection<T>
IList<T>
IDictionary<TKey,TValue>
ISet<T>
是什么让这些类型的集合获得定义良好的接口?为什么堆栈和队列不保证接口?
答案 0 :(得分:12)
好吧,因为从这些接口到实现它们的类会有一对一的映射(最新的ConcurrentQueue
除外)。但是其他提到的接口有很多实现它们的类。
扩大一点。我们无法知道BCL团队的真正动机。但我有一种感觉,当他们创建Queue
和Stack
这些类看起来如此微不足道时,他们决定不将它们抽象出接口。原因很明显:类看起来很简单但同时完成,因此没有理由在BCL中创建它们的不同实现。然后来了ConcurrentQueue
,之前的陈述变得有点不正确。
因为它指出Queue
和ConcurrentQueue
没有那么相似,所以要让它们实现单一接口。
答案 1 :(得分:3)
我猜你没有看到Stack或Queue接口是因为集合的性质。您列出的具有接口的集合接口是随机访问,而堆栈和队列则不是。它们必须以非常特殊的方式访问(FIFO或LIFO),因此通常不能使用。因此,将这些集合用作通用实现而不是通过接口是有意义的。换句话说,由于LIFO / FIFO对集合的约束,实现理论IStack或IQueue的类几乎没有(或没有)可以做到不同。
要实现这个想法,您可以创建自己的IStack和/或IQueue,然后在类中实现它们。您将看到您公开的功能将完全传递。例如。您最终只需将请求和结果转发或返回到内部堆栈或队列集合。在该传递功能中,很少或根本没有潜在的增值。
答案 2 :(得分:3)
为什么应该 .NET框架有IQueue<T>
和IStack<T>
接口?他们会买什么?
是什么使这些类型的集合 获得定义良好的接口?
基类库实际上使用了所有这些接口(IList
等):在每种情况下,还有许多其他类,与具体类型相比,它与接口抽象交互更有意义
为什么堆栈和队列不保证 界面?
可能是因为没有任何BCL类需要IStack<T>
和IQueue<T>
,并且这些抽象没有明显或可能的用例。
我意识到这不是一个令人满意的哲学答案,但看起来框架设计师对于什么得到接口非常务实:他们在需要时制作它们。
答案 3 :(得分:3)
我认为.NET 4 ConcurrentQueue<T>
和ConcurrentStack<T>
中新类的存在证明了你应该有IQueue<T>
和IStack<T>
接口。即使它们最初不存在,也应该在.NET 4中添加它们。
我过去必须在.NET中创建自己的自定义Stack实现,并同意拥有标准接口会有所帮助。
答案 4 :(得分:2)
我认为这是因为Stack和Queue是非常特殊的概念,据我所知,没有其他类实现特殊形式的堆栈或队列。
修改强>
好的,现在有ConcurrentQueue<T>
,这似乎否定了我的结论。也许,在C#1.0仍处于测试阶段的时代,语言设计师认为永远不会有一种特殊形式的队列/堆栈,现在为它引入一个接口为时已晚。
这是很多猜测。我希望,Eric Lippert会看到这个问题并发表“官方”声明。 : - )
答案 5 :(得分:0)
我怀疑有什么特别的原因。如果我有我的druthers,那么会有更多离散定义的接口,即使没有单独实现它们的类。例如,我可能实现了QueueStack(Of T),它将实现IGetNext(Of T),IGetNextWait(Of T)和IClear(Of T),以及IQueue(Of T),IWaitQueue(Of T), IStack(Of T)和IWaitStack(Of T)。消费对象的人可以狭隘地指定他们实际需要的东西,而实施者只需要实现他们声称支持的东西。