Restituisce interfaccia o classe

9

Supponiamo che abbia un metodo

public List<User> GetBatchOfUsers(IEnumerable<int> userIDs)
{
    List<User> users = new List<User>();

    // some database stuff

    return users;
}

Ho letto che sarebbe meglio restituire un'interfaccia ( IList o IEnumerable ) anziché restituire List . Alcuni argomenti che ho sentito per averlo fatto sono che nasconde i dati e offre allo sviluppatore dell'API la flessibilità di modificare la rappresentazione interna dei dati in un secondo momento.

La mia preoccupazione per il ritorno di un IEnumerable è che si perde la funzionalità, ad esempio l'accesso casuale e la proprietà Count .

So che accettare un IEnumerable come parametro ha senso, in quanto offre al consumatore la massima flessibilità per inviare dati al mio metodo, l'insieme minimalista di requisiti per il metodo da utilizzare.

Qual è la migliore pratica per il tipo di reso?

    
posta Matthew 08.08.2012 - 05:23
fonte

4 risposte

9

In generale, puoi iniziare con le interfacce e spostarti solo per inserire il tipo concreto come tipo di ritorno se ritieni di utilizzare i metodi aggiuntivi più frequentemente del previsto.

Bene, se si restituisce un'interfaccia, si mantiene più flessibilità. È possibile modificare l'implementazione in un secondo momento per restituire un tipo concreto diverso. D'altro canto, fornisce ovviamente al chiamante meno informazioni, quindi potrebbero non essere in grado di eseguire determinate operazioni. (Ad esempio: se si restituisce List<T> , il chiamante può utilizzare ConvertAll ecc ... che non possono se si dichiara solo che si restituisce IList<T> .) In alcune situazioni è opportuno specificare il tipo concreto.

Per quanto riguarda il metodo Count o Sort, non ci sono interfacce di raccolta standard per questo. Tuttavia, potresti scrivere un metodo di estensione per ordinare o contare qualsiasi IList.

    
risposta data 08.08.2012 - 05:36
fonte
1

Se hai bisogno che la tua collezione abbia un Count puoi usare ICollection<T> , che è abbastanza generale.

    
risposta data 08.08.2012 - 09:03
fonte
1

Ritorna ciò che è prudente per il metodo che stai definendo. È ciò che stai facendo restituendo una serie di elementi (l'attenzione è rivolta agli oggetti) o restituisce una raccolta di elementi (l'attenzione è rivolta alla raccolta nel suo complesso)? Vale la pena consentire la variazione nell'implementazione della collezione? Se non avrà mai senso usare un generatore o HashSet , usa solo List .

    
risposta data 08.08.2012 - 13:13
fonte
1

Specifico per il metodo di esempio: hai ragione che restituire IEnmuerable<T> significherebbe perdere la funzionalità di Count e indicizzazione (anche se potresti usare i metodi LINQ Count() e ElementAt() , che sono implementati in modo efficiente se il tipo in cui sono utilizzati implementa effettivamente IList<T> ).

Se hai restituito IList<T> , potresti perdere alcune funzionalità, ma probabilmente il guadagno in generalità ne vale la pena.

Ma ancora meglio sarebbe qualcosa tra IEnumerable<T> e IList<T> , perché molto probabilmente non ha senso che il consumatore muti la collezione restituita, ma ha senso per lui usare Count o indicizzazione .

In .Net 4.5, esiste una tale interfaccia: IReadOnlyList<T> .

    
risposta data 08.08.2012 - 13:21
fonte

Leggi altre domande sui tag