Domanda

Attualmente sto codificando un semplice livello di accesso ai dati e mi chiedevo quale tipo avrei dovuto esporre agli altri livelli.

Implementerò internamente i dati come un elenco < > ;, ma ricordo di aver letto qualcosa sul non esporre il tipo di elenco ai consumatori se non necessario.

public List<User> GetAllUsers() // non C# users: that means List of User :)

Sai perché (google non ha aiutato)? Cosa esponi di solito per quel tipo di cose? IList? IEnumerable?

È stato utile?

Soluzione

Di solito è meglio esporre l'interfaccia meno potente con cui l'utente può ancora lavorare in modo significativo. Se l'utente necessita solo di alcuni dati enumerabili, restituisce IEnumerable < User > . Se ciò non bastasse perché l'utente deve essere in grado di modificare l'elenco (attenzione! Spesso non dovrebbe essere il caso), restituisci un IList < User > .

/ EDIT:

Joel pone una domanda valida nel suo commento: perché in effetti esporre l'interfaccia meno potente invece di garantire all'utente la massima potenza? (Parafrasato)

L'idea alla base di ciò è che il metodo che restituisce i dati potrebbe non aspettarsi che l'utente ne modifichi il contenuto: Un altro metodo della classe potrebbe ancora prevedere che l'elenco non sia vuoto dopo che è stato restituito un riferimento ad esso. Immagina che l'utente rimuova tutti i dati dall'elenco. L'altro metodo ora deve verificare ulteriormente che ele potrebbe non essere stato necessario.

Ancora più importante, questo espone parti dell'implementazione interna attraverso il tipo restituito. Se in futuro dovrò cambiare l'implementazione in modo che non utilizzi più un contenitore IList , ho un problema: o ho bisogno di cambiare il contratto del metodo, introducendo una modifica rivoluzionaria. Oppure devo copiare i dati in un contenitore di elenchi.

Ad esempio, immagina che un'implementazione efficiente utilizzi un dizionario e restituisca semplicemente la raccolta Valori che non implementa IList .

Altri suggerimenti

Sicuramente un ISomething. L'uso di un'interfaccia ridurrà l'accoppiamento e renderà più semplice modificare i dettagli dell'implementazione del livello dati lungo la strada. Quale interfaccia dipende dalle circostanze. IList è buono, ma a volte potresti aver bisogno della funzionalità ICollection o vuoi specificare valori ReadOnly.

Dovresti pensare attentamente prima di restituire IEnumerable. Se il codice sottostante utilizza "rendimento" per generare IEnumerable, o sta usando LINQ, finirai per tenere aperte tutte le risorse utilizzate.

È necessario copiare IEnumerable in un altro IEnumerable prima di restituirlo. Usando IList, rendi questo un requisito, in modo che nessuno possa inavvertitamente restituire un IEnumerable.

D'altra parte, la restituzione di un IList implica al chiamante che possono modificare l'elenco restituito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top