队列 Queue<T> 实际上实现了什么?

6

当我试图通过包装通用队列来实现自己的队列时,我注意到队列实现了ICollection。然而,ICollection.CopyTo的方法签名如下:

void CopyTo(
    Array array,
    int index)

通用队列 Queue.CopyTo 方法的方法签名为:

public void CopyTo(
    T[] array, 
    int arrayIndex)

这与ICollection.CopyTo的通用版本的签名相同。我感到困惑的原因是,泛型队列似乎没有实现通用的ICollection,而是实现了标准的ICollection。那么这里到底发生了什么呢?

3个回答

9
根据文档
public class Queue<T> : IEnumerable<T>, ICollection, IEnumerable

因此,它实现了通用的 IEnumerable<T> 接口,但是非通用的 ICollection 接口。
不要被名称的相似性所迷惑 - ICollectionICollection<T> 是完全独立的接口,虽然像这样(实现一些通用接口,但只有非通用其他接口)是不寻常的,但是完全合法。
我怀疑设计师们真的不想在 Queue<T> 中支持 ICollection<T> 的各个方面,但同样他们想要实现 ICollection,以便让人们无痛升级从非通用 Queue 类。

编辑:正如Dennis的答案中所指出的那样,ICollection.CopyToQueue<T>中是显式实现的。这意味着您只能通过类型为ICollection的表达式访问该签名。例如:

Queue<string> queue = new Queue<string>();
Array array = new Button[10];
queue.CopyTo(array, 0, queue.Count); // Compilation failure...
ICollection collection = (ICollection) queue;
collection.CopyTo(array, 0, queue.Count); // Compiles, but will go bang

使用强类型数组的方法可以实现ICollection<T>.CopyTo,但是ICollection<T>AddRemove方法不存在 - 相反,你应该使用EnqueueDequeue来操作值。

1
天啊,这些接口真是让人头疼。 - BoltClock
@BoltClock:是的。我可以列举出困难,但我太懒了。 - Jon Skeet
1
这是一个不错的回答,但它仅仅回答了问题的标题。有关两个不同签名的问题的答案在Dennis Traub的回答中给出。 - Adam

4

2
因为 ICollection<T> 包含一个可以从集合中的任何位置移除项的 Remove 方法。但对于 Queue 来说不适用,因为你只能移除顶部的项而不必重新构建整个队列。

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