2011-01-13 12 views
9

ho un po 'di classe con List -property:Read-Only List in C#

class Foo { 
    private List<int> myList; 
} 

voglio fornire l'accesso a questo campo solo per la lettura.

I.e. Voglio proprietà con accesso a Enumerable, Count, ecc. E senza accesso a Clear, Add, Remove, ecc. Come posso farlo?

+0

ho intenzione di andare un testa e cambiare il titolo del questa domanda in sola lettura perché la sola lettura e l'immutabilità sono due argomenti molto diversi, anche se correlati, preferirei se non li mescolassimo. Se stai cercando l'immutabilità, controlla http://stackoverflow.com/a/9009748/58961. –

risposta

25

Se si desidera una visualizzazione di sola lettura di un elenco, è possibile utilizzare ReadOnlyCollection<T>.

class Foo { 
    private ReadOnlyCollection<int> myList; 
} 
+3

O, più precisamente, una variabile 'Lista ' privata e una proprietà 'ReadOnlyCollection pubblica con un' get {} 'che restituisce la variabile. –

+3

@Victor: ciò darebbe al codice chiamante l'accesso alla lista mutabile mediante un cast semplice. Probabilmente non è quello che l'OP vuole. La proprietà readonly potrebbe 'restituire new ReadOnlyCollection (myList);' comunque. –

+8

ReadOnlyCollection non è veramente immutabile dato che contiene un puntatore all'elenco originale - se aggiungi qualcosa al tuo elenco, l'istanza readOnly può accedere a questo nuovo elemento ... ma, hai ragione, quando si tratta di modifiche- metodi - questi sono mancanti! –

0

Se dichiari un elenco di sola lettura nella tua classe, sarai comunque in grado di aggiungere elementi.

Se non si desidera aggiungere o modificare nulla, si consiglia di utilizzare ReadOnlyCollection<T> come suggerito da Darin.

Se si desidera aggiungere, rimuovere elementi dall'elenco ma non si desidera modificare il contenuto, è possibile utilizzare uno readonly List<T>.

9

vorrei andare per

public sealed class Foo 
{ 
    private readonly List<object> _items = new List<object>(); 

    public IEnumerable<object> Items 
    { 
     get 
     { 
      foreach (var item in this._items) 
      { 
       yield return item; 
      } 
     } 
    } 
} 
+4

Perché preoccuparsi della rottura del rendimento alla fine? –

+0

Anche il Foo potrebbe implementare IEnumerable – Turowicz

+0

@Jon Skeet: copia il passato ... all'inizio avevo un '// TODO', ma lo ho sostituito con un foreach ... grazie per quel suggerimento! –

8

È possibile esporre un List<T> come ReadOnlyCollection<T> utilizzando il metodo AsReadOnly()

class Foo { 

    private List<int> myList; 

    public ReadOnlyCollection<int> ReadOnlyList { 
    get { 
     myList.AsReadOnly(); 
    } 
    } 
} 

La cosa accurata è che se si aggiunge/rimuovere qualsiasi cosa dalla lista privata ciò si riflette anche nella ReadOnlyCollection restituita

+0

Bello e pulito, esattamente quello che volevo. – AnthonyVO

5

Ora esiste una libreria di Raccolte immutabili che fa esattamente questo. Che è possibile installare tramite nuget.

Le classi di raccolta immutabili sono supportate a partire da .NET Framework 4.5.

https://msdn.microsoft.com/en-us/library/dn385366%28v=vs.110%29.aspx

Lo spazio dei nomi System.Collections.Immutable fornisce generici immutabile tipi di raccolta che è possibile utilizzare per questi scenari, tra cui: ImmutableArray <T>, ImmutableDictionary < TKey, TValue >, ImmutableSortedDictionary <T>, ImmutableHashSet <T>,.210 ImmutableList <T>, ImmutableQueue <T>, ImmutableSortedSet <T>, ImmutableStack <T>

Esempio di utilizzo:

class Foo 
{ 
    public ImmutableList<int> myList { get; private set; } 

    public Foo(IEnumerable<int> list) 
    { 
     myList = list.ToImmutableList(); 
    } 
}