Elenco di sola lettura o elenco non modificabile in .NET 4.0


100

Da quello che posso dire, .NET 4.0 manca ancora di elenchi di sola lettura. Perché il framework manca ancora di questa funzionalità? Non è questa una delle funzionalità più comuni per la progettazione guidata dal dominio ?

Uno dei pochi vantaggi che Java ha rispetto a C # è questo sotto forma del metodo Collections.unmodifiablelist (list) , che sembra essere atteso da tempo in IList <T> o List <T>.

L'utilizzo IEnumerable<T>è la soluzione più semplice alla domanda: ToListpuò essere utilizzato e restituisce una copia.


Sembra che l'unico vero modo per avere una vera sola lettura List<T>sia scrivere la tua, non esiste una classe incorporata che io sappia che supporti tutte le funzionalità di "sola lettura" di List<T>out of the box come Contains, query LINQ, ecc.
jrh

Risposte:


146

Stai cercando ReadOnlyCollection, che esiste da .NET2.

IList<string> foo = ...;
// ...
ReadOnlyCollection<string> bar = new ReadOnlyCollection<string>(foo);

o

List<string> foo = ...;
// ...
ReadOnlyCollection<string> bar = foo.AsReadOnly();

Questo crea una sola lettura vista , che riflette le modifiche apportate alla raccolta avvolto.


1
Mi sento un po 'stupido ad aver fatto questa domanda ora - e non sapevo di ReadOnlyCollection
Chris S

54
non essere - nemmeno io, quando sono andato a cercare la stessa cosa e ho trovato la tua domanda
Roland Tepp

9
È una classe fastidiosamente difficile da trovare. È nello spazio dei nomi System.Collections.ObjectModel invece di System.Collections.Generic dove mi aspetterei di trovarlo. Suppongo sia perché era lì prima che esistesse lo spazio dei nomi generico. Tuttavia, mi aspetto che la classe base rimanga in ObjectModel e la classe generica venga aggiunta a Generic. Suppongo che avessero le loro ragioni, ma lo trovo fastidioso.
BlueMonkMN

5
@BlueMonkMN: Fare riferimento a questo articolo per scoprire perché è separato dallo spazio dei nomi Collections.Generic.
Uchitha

7
Ma questa non è una lista, è una raccolta. Quindi, se lo usi, devi modificare tutto il tuo codice per usare Collection invece di List.
Roman Zabicki



11

Se il modello più comune dell'elenco è quello di iterare attraverso tutti gli elementi, IEnumerable<T>o IQueryable<T>può anche agire efficacemente come un elenco di sola lettura.


4
Se esponi l'elenco come IEnumerable, il consumatore potrebbe semplicemente restituirlo a List e modificarlo.
JulianR

4
Certo, ma non vuole essere una misura a prova di proiettile: potresti anche leggere i campi privati ​​e rintracciare l'elenco originale. È più come descrivere l'intento che questo dovrebbe rimanere di sola lettura.
Ana Betts,

5
Non stai modificando l'elenco originale ToList()nemmeno chiamando , ma solo una copia
Chris S

Nota che IEnumerablenon è un set completo di metodi di "sola lettura", ad esempio non contiene metodi come Contains.
jrh

8

Nella 2.0 puoi chiamare AsReadOnlyper ottenere una versione di sola lettura dell'elenco. O avvolgere un esistente IListin un ReadOnlyCollection<T>oggetto.


questo è l'equivalente di Collections.unmodifiablelist (list) che stavo cercando
Chris S,

Mi mancava questo in .NET 4 perché stavo usando un IList <T> invece di un vero List <T>. Assicurati di notare che AsReadOnly è ancora disponibile in .NET 4 fintanto che hai a che fare con un List <T>.
BlueMonkMN

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.