Danh sách chỉ đọc hoặc danh sách không thể sửa đổi trong .NET 4.0


100

Từ những gì tôi có thể nói, .NET 4.0 vẫn thiếu danh sách chỉ đọc. Tại sao khung công tác vẫn thiếu chức năng này? Đây không phải là một trong những phần chức năng phổ biến nhất cho thiết kế hướng miền ?

Một trong những ưu điểm của Java so với C # là nó ở dạng phương thức Collections.unmodifiablelist (list) , phương thức này dường như đã quá hạn trong IList <T> hoặc List <T>.

Sử dụng IEnumerable<T>là giải pháp dễ dàng nhất cho câu hỏi - ToListcó thể được sử dụng và trả về một bản sao.


Có vẻ như cách thực sự duy nhất để có chỉ đọc thực sự List<T>là viết của riêng bạn, không có lớp học nào được xây dựng sẵn mà tôi biết hỗ trợ tất cả các tính năng "chỉ đọc" List<T>ngoài hộp như Contains, truy vấn LINQ, v.v.
jrh

Câu trả lời:


146

Bạn đang tìm kiếm ReadOnlyCollection, đã có từ thời .NET2.

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

hoặc là

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

Điều này tạo ra một chế độ xem chỉ đọc , phản ánh những thay đổi được thực hiện đối với bộ sưu tập được bao bọc.


1
Tôi cảm thấy một chút ngu ngốc khi hỏi câu hỏi này ngay bây giờ - và không biết về ReadOnlyCollection
Chris S

54
đừng - không phải đã làm tôi, khi tôi đã đi tìm kiếm những điều tương tự và thấy câu hỏi của bạn
Roland Tepp

9
Đó là một lớp học khó tìm. Nó nằm trong không gian tên System.Collections.ObjectModel thay vì System.Collections.Generic, nơi tôi mong đợi sẽ tìm thấy nó. Tôi cho rằng đó là vì đó là nơi nó đã có trước khi không gian tên Chung tồn tại. Tôi vẫn mong đợi lớp cơ sở vẫn còn trong ObjectModel và lớp chung sẽ được thêm vào Generic. Tôi cho rằng họ có lý do của họ, nhưng tôi thấy thật khó chịu.
BlueMonkMN

5
@BlueMonkMN: Vui lòng tham khảo bài viết này để tìm hiểu lý do tại sao nó tách biệt khỏi không gian tên Collections.Generic.
Uchitha

7
Nhưng đó không phải là Danh sách, mà là Bộ sưu tập. Vì vậy, nếu bạn sử dụng nó, bạn cần sửa đổi tất cả mã của mình để sử dụng Bộ sưu tập thay vì Danh sách.
Roman Zabicki

13

Đối với những người thích sử dụng giao diện: .NET 4.5 thêm IReadOnlyListgiao diện chung được thực hiện bởi List<T>ví dụ.

Nó tương tự như IReadOnlyCollectionvà thêm một thuộc tính Itemchỉ mục.



11

Nếu mẫu phổ biến nhất của danh sách là lặp qua tất cả các phần tử IEnumerable<T>hoặc IQueryable<T>có thể hoạt động hiệu quả như một danh sách chỉ đọc.


4
Nếu bạn hiển thị Danh sách của mình dưới dạng IEnumerable, thì người tiêu dùng có thể chỉ cần chuyển nó trở lại Danh sách và sửa đổi nó.
JulianR

4
Tất nhiên, nhưng nó không nhằm mục đích là một biện pháp chống đạn - bạn cũng có thể đọc các trường riêng tư và theo dõi danh sách ban đầu. Nó giống như mô tả ý định rằng điều này sẽ ở chế độ chỉ đọc.
Ana Betts

5
Bạn cũng không phải sửa đổi danh sách ban đầu bằng cách gọi ToList(), chỉ là một bản sao
Chris S

Lưu ý rằng đó IEnumerablekhông phải là một tập hợp đầy đủ các phương thức "chỉ đọc", ví dụ như nó không chứa các phương thức như Contains.
jrh

8

Trong 2.0, bạn có thể gọi AsReadOnlyđể nhận phiên bản chỉ đọc của danh sách. Hoặc bọc một hiện có IListtrong một ReadOnlyCollection<T>đối tượng.


đó là tương đương với Collections.unmodifiablelist (danh sách) Tôi đã sau
Chris S

Tôi đã bỏ lỡ điều này trong .NET 4 vì tôi đang sử dụng IList <T> thay vì Danh sách thực <T>. Đảm bảo nhận thấy rằng AsReadOnly vẫn có sẵn trong .NET 4 miễn là bạn đang xử lý aa List <T>.
BlueMonkMN

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.