2012-10-10 2 views
6

Lors de la tentative d'implémentation de ma propre file d'attente en enveloppant la file d'attente générique, j'ai remarqué que Queue implémente ICollection. Cependant, la signature de la méthode de ICollection.CopyTo est comme suitQue fait réellement la file d'attente <T>

void CopyTo(
    Array array, 
    int index) 

Alors que la signature de la méthode de la Queue.CopyTo générique est

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

C'est la même que la signature de la version générique de ICollection .Copier. Ma confusion vient du fait que la file d'attente générique ne semble pas implémenter l'ICollection générique, mais implémente à la place l'ICollection standard. Alors qu'est-ce qui se passe exactement ici?

+0

duplication possible de [C# Stack implémente ICollection, mais a des méthodes de ICollection ] (http://stackoverflow.com/questions/10589803/c-sharp-stack-implements-icollection-but-has-methods-from- icollectiont) – nawfal

Répondre

9

Comme par the documentation:

public class Queue<T> : IEnumerable<T>, ICollection, IEnumerable 

Il implémente l'interface générique IEnumerable<T>, mais l'interface non générique ICollection. Ne laissez pas la similitude des noms vous tromper - ICollection et ICollection<T> sont des interfaces entièrement séparées, et bien que quelque chose comme ceci (implémentant des interfaces génériques mais seulement d'autres interfaces non génériques) soit inhabituel, c'est tout à fait légitime.

je soupçonne qu'il y avait divers aspects de ICollection<T> que les concepteurs vraiment ne voulaient pas soutenir dans Queue<T>, mais aussi qu'ils voulaient mettre en œuvre ICollection pour permettre aux gens de mise à niveau de la classe non générique Queue sans douleur.

EDIT: Comme indiqué dans la réponse de Dennis, ICollection.CopyTo est implémenté explicitement dans Queue<T>. Cela signifie que vous pouvez seulement accéder à cette signature via une expression de type ICollection. Par exemple:

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 

La méthode de prendre un tableau fortement typé serait valable pour mettre en œuvre ICollection<T>.CopyTo, mais les Add et Remove méthodes de ICollection<T> ne sont pas présents - à la place, vous êtes censé Enqueue et Dequeue valeurs .

+1

[Gosh, ces interfaces sont un mal de tête collectif.] (http://tvtropes.org/pmwiki/pmwiki.php/Main/IncrediblyLamePun) – BoltClock

+0

@BoltClock: Oui.J'énumérerais les difficultés, mais je suis trop paresseux. –

+1

C'est une bonne réponse, mais elle * seulement * répond au * titre * de la question. La réponse à la question sur les deux signatures différentes est donnée dans [la réponse de Dennis Traub] (http://stackoverflow.com/a/12826832/1106367). – Adam

2

Parce que ICollection<T> contient une méthode Remove qui supprime un élément de tout lieu la collection. Cela ne s'applique pas à une file d'attente, car vous ne pouvez supprimer que l'élément supérieur sans reconstruire la file d'attente entière.