Lista tylko do odczytu lub lista niemodyfikowalna w .NET 4.0


100

Z tego, co wiem, w .NET 4.0 nadal brakuje list tylko do odczytu. Dlaczego frameworkowi nadal brakuje tej funkcjonalności? Czy nie jest to jedna z najpopularniejszych funkcji w projektowaniu opartym na domenie ?

Jedną z nielicznych zalet Java w porównaniu z C # jest to w postaci metody Collections.unmodifiablelist (list) , która wydaje się być od dawna spóźniona w IList <T> lub List <T>.

Użycie IEnumerable<T>jest najłatwiejszym rozwiązaniem pytania - ToListmożna z niego skorzystać i zwrócić kopię.


Wydaje się, że jedynym prawdziwym sposobem, aby mieć prawdziwe tylko List<T>do odczytu, jest napisanie własnej, nie ma wbudowanej klasy, o której wiem, która obsługuje wszystkie funkcje „tylko do odczytu”, takie List<T>jak Containszapytania LINQ itp.
jrh

Odpowiedzi:


146

Szukasz tego ReadOnlyCollection, co istnieje od .NET2.

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

lub

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

Tworzy to widok tylko do odczytu , który odzwierciedla zmiany wprowadzone w opakowanej kolekcji.


1
Czuję się trochę głupio, zadając to pytanie teraz - i nie wiem o ReadOnlyCollection
Chris S

54
nie bądź - ja też nie, kiedy poszedłem szukać tego samego i znalazłem Twoje pytanie
Roland Tepp

9
To irytująco trudne do znalezienia zajęcia. Znajduje się w przestrzeni nazw System.Collections.ObjectModel zamiast w System.Collections.Generic, gdzie spodziewałbym się go znaleźć. Przypuszczam, że dzieje się tak, ponieważ to było miejsce, w którym istniała przestrzeń nazw Generic. Nadal oczekiwałbym, że klasa bazowa pozostanie w ObjectModel, a klasa generyczna zostanie dodana do Generic. Przypuszczam, że mieli swoje powody, ale mnie to denerwuje.
BlueMonkMN

5
@BlueMonkMN: Zapoznaj się z tym artykułem, aby dowiedzieć się, dlaczego jest on oddzielny od przestrzeni nazw Collections.Generic.
Uchitha

7
Ale to nie jest lista, to kolekcja. Jeśli więc go używasz, musisz zmodyfikować cały kod, aby używał kolekcji zamiast listy.
Roman Żabicki



11

Jeśli najczęstszym wzorcem listy jest iteracja przez wszystkie elementy, IEnumerable<T>lub IQueryable<T>może również skutecznie działać jako lista tylko do odczytu.


4
Jeśli ujawnisz swoją Listę jako IEnumerable, konsument może po prostu przesłać ją z powrotem do List i zmodyfikować.
JulianR

4
Oczywiście, ale nie ma to być środek kuloodporny - prawdopodobnie mógłbyś również przeczytać pola prywatne i odszukać oryginalną listę. To bardziej opisanie zamiaru, że powinno to pozostać tylko do odczytu.
Ana Betts

5
Nie zmieniasz oryginalnej listy, dzwoniąc ToList(), tylko kopię
Chris S,

Zauważ, że IEnumerablenie jest to pełny zestaw metod „tylko do odczytu”, na przykład nie zawiera metod takich jakContains .
jrh

8

W wersji 2.0 możesz zadzwonić, AsReadOnlyaby uzyskać wersję listy tylko do odczytu. Lub owinąć istniejący IListw ReadOnlyCollection<T>obiekcie.


to odpowiednik Collections.unmodifiablelist (lista), po którym byłem
Chris S

Brakowało mi tego w .NET 4, ponieważ używałem IList <T> zamiast prawdziwego List <T>. Pamiętaj, aby zauważyć, że AsReadOnly jest nadal dostępny w .NET 4, o ile masz do czynienia z aa List <T>.
BlueMonkMN

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.