Differenza tra le varie interfacce generiche di raccolta in C #

11

Ho giocato a C # per lo sviluppo di Windows e ASP.net MVC da un po 'di tempo. Ma non sono ancora chiaro su alcune aree. Sto cercando di capire la differenza fondamentale tra i problemi di prestazioni e l'utilizzo e l'interscambio di tipi simili di Generico Interfacce di raccolta .

Qual è la differenza di base tra IEnumerable<T> , ICollection<T> , List<T>(Class) ?

Mi sembra di usarli e scambiarli senza vedere alcun problema nelle mie applicazioni. Inoltre, ci sono altre raccolte generiche simili come queste che possono essere scambiate con quelle tre?

    
posta Pankaj Upadhyay 08.11.2011 - 08:22
fonte

3 risposte

19

List < T > è una classe e implementa sia il ICollection < T > e Interfacce IEnumerable < T > . Inoltre, ICollection < T > estende IEnumerable < T > interfaccia. Non sono intercambiabili, almeno non da tutti i punti di vista.

Se hai una lista < T & gt ;, sei sicuro che questo oggetto implementa metodi e proprietà che devono essere implementati da ICollection < T > e IEnumerable < T > interfaccia. Il compilatore lo sa e puoi lanciarli "down" su un ICollection < T > o un IEnumerable < T > implicitamente. Tuttavia, se disponi di un ICollection < T > devi prima verificare esplicitamente nel tuo codice se è un elenco < T > o qualcos'altro, forse un dizionario < T > (dove T è un KeyValuePair ) prima di inviarlo a ciò che desideri.

Sai che ICollection estende IEnumerable, quindi puoi lanciarlo su un oggetto IEnumerable. Ma se si ha solo un oggetto IEnumerable, di nuovo non si garantisce che si tratti di un elenco. Potrebbe essere, ma potrebbe essere qualcos'altro. Dovresti aspettarti un'eccezione di cast non valida se tenti di trasmettere una lista < T > a un dizionario < T > per esempio.

Quindi non sono "intercambiabili".

Inoltre, ci sono molte interfacce generiche, controlla cosa puoi trovare in System.Collections.Generic spazio dei nomi.

Modifica: per quanto riguarda il tuo commento, non c'è assolutamente alcuna penalità legata alle prestazioni se usi List < T > o una delle interfacce che implementa. Dovrai comunque creare un nuovo oggetto, controlla il seguente codice:

List<T> list = new List<T>();
ICollection<T> myColl = list;
IEnumerable<T> myEnum = list;

elenco , myColl e myEnum puntano tutti allo stesso oggetto. Sia che tu lo dichiari come Lista o ICollection o IEnumerable, sto ancora richiedendo al programma di creare una Lista. Potrei aver scritto questo:

ICollection<T> myColl = new List<T>();

myColl , in fase di runtime è ancora un elenco.

Tuttavia , questo è il punto più importante ... per ridurre l'accoppiamento e aumentare la manutenibilità devi sempre dichiarare le tue variabili e i parametri del metodo utilizzando il minimo possibile denominatore possibile per te, che sia un'interfaccia o una classe astratta o concreta.

Immagina che l'unica cosa di cui il metodo "PerformOperation" abbia bisogno è enumerare gli elementi, fare un po 'di lavoro ed uscire, in quel caso non hai bisogno di altri cento metodi disponibili in List < T & gt ;, hai solo bisogno di ciò che è disponibile in IEnumerable < T & gt ;, quindi dovrebbe essere applicato quanto segue:

public void PerformOperation(IEnumerable<T> myEnumeration) { ... }

In questo modo tu e altri sviluppatori sapete che qualsiasi oggetto di una classe che implementa IEnumerable < T > un'interfaccia può essere data a questo metodo. Può essere un elenco, un dizionario o una classe di raccolta personalizzata che un altro sviluppatore ha scritto.

Se al contrario specifichi di aver bisogno esplicitamente di una lista concreta < T > (e anche se raramente accade nella vita reale, può ancora succedere), tu e altri sviluppatori sapete che deve essere una lista o un'altra classe concreta ereditata da List.

    
risposta data 08.11.2011 - 08:34
fonte
6

Dai un'occhiata alle pagine MSDN per ICollection e IEnumerable .

In termini molto astratti, questo è il modo in cui concepisco questi tipi.

Un IEnumerable è tutto ciò che può essere enumerato - cioè, ripetuto. Non significa necessariamente una "collezione"; ad esempio, un IQueryable implementa IEnumerable e non è una raccolta, ma è qualcosa che può essere interrogato per restituire oggetti. Per implementare IEnumerable, un oggetto deve essere in grado di restituire un oggetto solo quando richiesto. Potrei dire che ho un Enumerable di compiti che farò oggi (non è una lista perché non l'ho scritta o formulata, ma potrei dirti cosa farò ora, e se hai chiesto "e poi?" sarei in grado di dirti il seguente compito).

Un ICollection è più concreto di un oggetto IEnumerable. Una differenza fondamentale è che una Collezione sa quanti oggetti contiene; per capire quanti oggetti ci sono in un Enumerable, li fai scorrere e li contiamo in modo efficace:

Me: Guys, how many items do you each have in you?

Enumerable: I don't really know. Well, here's one item. I've got another one, so that's two. And another one, so that's three... and another one... ok so that's 2382. No more items, so I've got 2382. Don't ask me again because I'll have to go through them all again.

Collection: I've got 2382 items. I already know that.

Una raccolta è in genere qualcosa che già conosce tutti i suoi elementi e non dovrà andare a cercarli o generarli quando li chiedi. È più ... concreto di un Enumerable.

A mio parere il diverso tra un Enumerable e una Collection è molto più grande della differenza tra una Collection e una List. In effetti sto facendo fatica a pensare a una differenza pratica tra una raccolta e una lista, ma credo che List fornisca metodi migliori per la ricerca e l'ordinamento.

Altri tipi di raccolta includono Queue e Stack , oltre a Dictionary .

I nomi di questi tipi sono molto utili: puoi immaginare una coda e uno stack come le loro controparti reali e considerare le differenze che potresti avere con un elenco.

    
risposta data 08.11.2011 - 09:17
fonte
-1

IQueryable:

la query non viene eseguita fino a iterare realmente sugli articoli, magari facendo una .ToList ()

IEnumerable

elenco degli articoli di sola andata. Non puoi raggiungere "articolo 4" senza passare gli articoli da 0 a 3. elenco di sola lettura, non puoi aggiungerlo o rimuoverlo. È ancora possibile utilizzare l'esecuzione posticipata.

IList:

accesso casuale alla lista completa interamente in memoria supporta l'aggiunta e la rimozione

ICollection:

È tra IEnumerable e IList. Ciò che è "migliore" dipende dalle tue esigenze. Di solito un IEnumerable è "abbastanza buono" se si desidera visualizzare solo gli elementi. Almeno usa sempre la variante generica.

    
risposta data 25.07.2013 - 08:14
fonte

Leggi altre domande sui tag