Daftar hanya baca atau daftar yang tidak dapat dimodifikasi di .NET 4.0

100

Dari apa yang saya tahu, .NET 4.0 masih kekurangan daftar hanya-baca. Mengapa kerangka kerja masih kekurangan fungsi ini? Bukankah ini salah satu bagian fungsionalitas yang paling umum untuk desain berbasis domain ?

Salah satu dari sedikit keunggulan Java dibandingkan C # adalah dalam bentuk metode Collections.unmodifiablelist (daftar) , yang tampaknya sudah lama tertunda di IList <T> atau List <T>.

Menggunakan IEnumerable<T>adalah solusi termudah untuk pertanyaan - ToListdapat digunakan dan mengembalikan salinan.

Chris S
sumber
Sepertinya satu-satunya cara nyata untuk memiliki hanya baca yang sebenarnya List<T>adalah dengan menulis milik Anda sendiri, tidak ada kelas bawaan yang saya tahu yang mendukung semua fitur "hanya baca" di List<T>luar kotak seperti Contains, kueri LINQ, dll.
jrh

Jawaban:

146

Anda sedang mencari ReadOnlyCollection, yang sudah ada sejak .NET2.

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

atau

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

Hal ini menciptakan read-only pandangan , yang mencerminkan perubahan yang dibuat untuk koleksi dibungkus.

LukeH
sumber
1
Saya merasa agak bodoh karena menanyakan pertanyaan ini sekarang - dan tidak mengetahui tentang ReadOnlyCollection
Chris S
54
jangan - begitu pula saya, ketika saya pergi mencari hal yang sama dan menemukan pertanyaan Anda
Roland Tepp
9
Itu adalah kelas yang sangat sulit ditemukan. Ini ada di namespace System.Collections.ObjectModel bukan System.Collections.Generic di mana saya berharap untuk menemukannya. Saya kira itu karena di situlah sebelum namespace Generic ada. Masih saya berharap kelas dasar tetap di ObjectModel dan kelas generik akan ditambahkan ke Generik. Saya kira mereka punya alasan, tapi menurut saya itu menjengkelkan.
BlueMonkMN
5
@BlueMonkMN: Silakan lihat artikel ini untuk mencari tahu mengapa itu terpisah dari ruang nama Collections.Generic.
Uchitha
7
Tapi itu bukan Daftar, itu Koleksi. Jadi jika Anda menggunakannya, Anda perlu mengubah semua kode Anda untuk menggunakan Collection, bukan List.
Roman Zabicki
13

Bagi mereka yang suka menggunakan antarmuka: .NET 4.5 menambahkan IReadOnlyListantarmuka generik yang diimplementasikan oleh List<T>misalnya.

Ini mirip dengan IReadOnlyCollectiondan menambahkan Itemproperti pengindeks.

Martin
sumber
11

Jika pola daftar yang paling umum adalah mengulang melalui semua elemen, IEnumerable<T>atau juga IQueryable<T>dapat bertindak sebagai daftar hanya-baca secara efektif.

Ana Betts
sumber
4
Jika Anda mengekspos Daftar Anda sebagai IEnumerable, maka konsumen dapat dengan mudah memasukkannya kembali ke List dan memodifikasinya.
JulianR
4
Tentu saja, tetapi ini tidak dimaksudkan sebagai tindakan antipeluru - Anda mungkin juga dapat membaca kolom pribadi dan melacak daftar aslinya. Ini lebih seperti mendeskripsikan maksud bahwa ini harus tetap hanya-baca.
Ana Betts
5
Anda juga tidak mengubah daftar asli dengan menelepon ToList(), cukup salin
Chris S
Perhatikan bahwa IEnumerableini bukan satu set lengkap metode "hanya baca", misalnya tidak berisi metode seperti Contains.
jrh
8

Dalam 2.0 Anda dapat menelepon AsReadOnlyuntuk mendapatkan versi hanya-baca dari daftar. Atau bungkus yang ada IListdi suatu ReadOnlyCollection<T>objek.

Paul Alexander
sumber
itu setara dengan Collections.unmodifiablelist (daftar) yang saya cari
Chris S
Saya melewatkan ini di .NET 4 karena saya menggunakan IList <T> daripada List <T> yang sebenarnya. Pastikan untuk memperhatikan bahwa AsReadOnly masih tersedia di .NET 4 selama Anda berurusan dengan Daftar <T>.
BlueMonkMN