Per rispondere alla parte "perché" della domanda sul perché no List<T>
, i motivi sono a prova di futuro e semplicità API.
A prova di futuro
List<T>
non è progettato per essere facilmente estensibile tramite la sottoclasse; è progettato per essere veloce per le implementazioni interne. Noterai che i metodi su di esso non sono virtuali e quindi non possono essere sovrascritti e non ci sono hook nelle sue operazioni Add
/ Insert
/ Remove
.
Ciò significa che se in futuro è necessario modificare il comportamento della raccolta (ad es. Per rifiutare oggetti null che le persone cercano di aggiungere o per eseguire lavori aggiuntivi quando ciò accade, ad esempio l'aggiornamento dello stato della classe), è necessario modificare il tipo di raccolta che ritorni a una sottoclasse, che sarà una rottura dell'interfaccia (ovviamente cambiare la semantica di cose come non consentire null può anche essere una modifica dell'interfaccia, ma cose come l'aggiornamento del tuo stato di classe interno non lo sarebbero).
Quindi restituendo una classe che può essere facilmente sottoclassata come Collection<T>
o un'interfaccia come IList<T>
, ICollection<T>
oppure IEnumerable<T>
è possibile modificare l'implementazione interna in un tipo di raccolta diverso per soddisfare le proprie esigenze, senza violare il codice dei consumatori perché può essere comunque restituito come il tipo che si aspettano.
Semplicità API
List<T>
contiene molte operazioni utili come BinarySearch
, Sort
e così via. Tuttavia, se questa è una raccolta che stai esponendo, è probabile che controlli la semantica dell'elenco e non i consumatori. Quindi, sebbene la tua classe internamente possa aver bisogno di queste operazioni, è molto improbabile che i consumatori della tua classe vogliano (o addirittura dovrebbero) chiamarli.
Pertanto, offrendo una classe o un'interfaccia di raccolta più semplice, riduci il numero di membri che gli utenti della tua API vedono e ne semplifica l'utilizzo.