2010-08-25 9 views
13

Ho notato nel codice di altre persone che i metodi che restituiscono raccolte generiche restituiranno quasi sempre un'interfaccia (ad esempio IEnumerable<T> o IList<T>) anziché un'implementazione concreta.Perché restituire un'interfaccia di raccolta anziché un tipo concreto?

Ho due domande correlate. In primo luogo, perché (se non lo è) è considerato meglio restituire un'interfaccia? In secondo luogo, esiste un'interfaccia di raccolta che include il metodo Sort (come fa List<T>)?

risposta

5

Da C# - List or IList

Se si sta esponendo la classe attraverso una biblioteca che gli altri useranno, tu, , in genere, vuoi esporlo tramite le interfacce anziché con le implementazioni concrete . Ciò ti sarà di aiuto se deciderai di modificare l'implementazione di in seguito nella classe per utilizzare un'altra classe di calcestruzzo . In tal caso gli utenti della libreria non avranno bisogno di aggiornare il loro codice poiché l'interfaccia non cambia.

Se lo si utilizza solo internamente, , potrebbe non interessarti troppo e utilizzare l'elenco potrebbe essere corretto.

+0

Grazie per questo - molto utile. E questa è la cosa - non sto scrivendo una libreria per uso esterno. Sto scrivendo una intranet per un'azienda in cui sono l'unico sviluppatore. Può rendere più difficile per me vedere lo scopo in alcune di queste cose. – David

+0

Sì, se è puramente interno e sicuramente sicuro che non sarà esposto al pubblico o a più parti del software, quindi restituire un oggetto List dovrebbe andare bene. Ma se ad esempio si tratta di una libreria di classi, e sebbene sia utilizzata solo per ora, potresti voler estendere la tua applicazione e usare di nuovo quella libreria, quindi sarai vincolato alla lista piuttosto che alla tua stessa implementazione. –

20

Per la prima domanda: se si restituisce un'interfaccia, si mantiene più flessibilità. È possibile modificare l'implementazione in un secondo momento per restituire un tipo concreto diverso. D'altra parte, ovviamente, il chiamante riceve meno informazioni, quindi potrebbe non essere in grado di eseguire determinate operazioni. Ad esempio, se si restituisce List<T>, il chiamante può utilizzare ConvertAll ecc. che non è possibile se si dichiara solo di restituire IList<T>. In alcune situazioni è opportuno specificare il tipo concreto; I generalmente preferisco iniziare almeno con le interfacce, e solo spostare il tipo concreto come tipo di ritorno se trovo che frequentemente voglio usare i metodi extra disponibili.

In secondo luogo, nessuna interfaccia di raccolta standard ha un metodo Sort. D'altra parte, è possibile scrivere un metodo di estensione per ordinare qualsiasi IList<T>. Personalmente di solito preferisco i metodi LINQ OrderBy, OrderByDescending, ThenBy e ThenByDescending ... anche se restituiscono una nuova sequenza, piuttosto che l'ordinamento in atto.

+2

Brilliant! Grazie per la risposta chiara alla mia domanda. – David

1

Non posso parlare per tutti ma generalmente lo faccio solo perché mi piace restituire solo ciò di cui ho bisogno. Perché restituire una collezione completa quando tutto ciò che serve è una collezione enumerabile che può essere ripetuta.

Per quanto riguarda l'altra parte della tua domanda si può sempre usare un IList e quindi utilizzare LINQ per ordinare:

list.OrderBy(a=>a.Id); 
+0

@downvoter cura di commentare ?? – spinon

+0

Grazie, ho capito ora. Non sapevo che avevo OrderBy disponibile perché era un metodo di estensione e non stavo usando lo spazio dei nomi. – David

+0

Grande. Sì, i metodi di estensione per LINQ sono fantastici. – spinon

2

Utilizziamo le interfacce per darci maggiore flessibilità nella nostra implementazione. Pertanto, se il metodo ha il tipo restituito di IEnumerable, è possibile modificare l'oggetto restituito da un elenco a un array senza alterare gli oggetti che dipendono dal metodo.

è anche espressiva: se si restituisce un IEnumerable, quando si utilizza l'oggetto è chiaro al codificatore che si cura solo che si tratta di una sorta di raccolta, piuttosto che un tipo specifico

Problemi correlati