2011-01-13 31 views
9

mam jakąś klasę z List -property:Read-Only listy w języku C#

class Foo { 
    private List<int> myList; 
} 

Chcę zapewnić dostęp do tego pola tylko do odczytu.

tj. Chcę mieć własność z dostępem do zmiennej, liczby itp. I bez dostępu do opcji Wyczyść, Dodaj, Usuń itd. Jak mogę to zrobić?

+0

mam zamiar iść do głowy i zmienić tytuł to pytanie jest tylko do odczytu, ponieważ tylko do odczytu i niezmienności są dwoma bardzo różnymi, aczkolwiek pokrewnymi tematami, wolałbym, żebyśmy ich nie miksowali. Jeśli szukasz niezmienności sprawdź http://stackoverflow.com/a/9009748/58961. –

Odpowiedz

25

Jeśli chcesz wyświetlić listę w trybie tylko do odczytu, możesz użyć ReadOnlyCollection<T>.

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

Albo, dokładniej, prywatna zmienna 'List ' i publiczna 'ReadOnlyCollection' z 'get {}', która zwraca zmienną. –

+3

@Victor: dałoby to kodowi wywołującemu dostęp do listy zmieniającej się za pomocą prostego rzutu. Prawdopodobnie nie tego, co chce OP. Właściwość readonly mogłaby "zwrócić nową ReadOnlyCollection (myList);' chociaż. –

+8

ReadOnlyCollection nie jest niezmienna, ponieważ zawiera wskaźnik do oryginalnej listy - jeśli dodasz coś do swojej listy, instancja readOnly może uzyskać dostęp do tego nowego elementu albo ... ale masz rację, jeśli chodzi o modyfikacje - metody - tych nie ma! –

0

Jeśli zadeklarujesz listę tylko do odczytu w klasie, nadal będziesz mógł dodawać do niej elementy.

Jeśli nie chcesz niczego dodawać ani zmieniać, powinieneś używać ReadOnlyCollection<T>, tak jak sugerował Darin.

Jeśli chcesz dodać, usunąć elementy z listy, ale nie chcesz zmieniać zawartości, możesz użyć numeru readonly List<T>.

9

chciałbym pójść na

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

Po co męczyć się z przerwą w produkcji na końcu? –

+0

Również Foo może zaimplementować IEnumerable – Turowicz

+0

@ Jon Skeet: po prostu skopiuj przeszłość ... na początku miałem '// TODO', ale zastąpiłem go foreach ... dzięki za podpowiedź! –

8

Można narazić List<T> jako ReadOnlyCollection<T> za pomocą metody AsReadOnly()

class Foo { 

    private List<int> myList; 

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

Schludny rzeczą jest to, że jeśli dodać/usunąć wszystko z listy prywatnej jest to również odzwierciedlone w zwróconej ReadOnlyCollection

+0

Ładne i czyste, dokładnie to, co chciałem. – AnthonyVO

5

Istnieje teraz biblioteka Niezmienna kolekcja, która robi dokładnie to. Które możesz zainstalować przez nuget.

niezmiennych klas kolekcji są obsługiwane począwszy od .NET Framework 4.5 .

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

Przestrzeń nazw generycznych System.Collections.Immutable zapewnia niezmienne typy kolekcji, które można wykorzystać do tych scenariuszy, w tym: ImmutableArray <T>, ImmutableDictionary < TKey, TValue >, ImmutableSortedDictionary <T>, ImmutableHashSet <T>, ImmutableList <T>, ImmutableQueue <T>, ImmutableSortedSet <T>, ImmutableStack <T>

Przykład użycia:

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

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