Vì tôi thường chỉ trả về các đối tượng bất biến (không thể sửa đổi) từ thuộc tính/phương thức, câu trả lời này giả định bạn muốn làm như vậy.
Đừng quên về ReadOnlyCollection<T>
trả về bộ sưu tập không thể thay đổi mà vẫn có thể được truy cập theo chỉ mục.
Nếu bạn đang sử dụng IEnumerable<T>
và phát hành loại của bạn vào vùng hoang dã không kiểm soát được, hãy cảnh giác về điều này:
class MyClass {
private List<int> _list;
public IEnumerable<int> Numbers {
get { return _list; }
}
}
Là một người dùng có thể thực hiện điều này và mess lên trạng thái nội bộ của lớp học của bạn:
var list = (List<int>)myClass.Numbers;
list.Add(123);
Điều này sẽ vi phạm ý định chỉ đọc cho thuộc tính. Trong những trường hợp như vậy, người khởi xướng của bạn sẽ trông giống như sau:
public IEnumerable<int> Numbers {
get { return new ReadOnlyCollection<int>(_list); }
}
Hoặc bạn có thể gọi _list.ToReadOnly()
. Tôi đã viết nó ra đầy đủ để hiển thị loại. Điều này sẽ ngăn chặn bất kỳ ai thay đổi trạng thái của bạn (trừ khi họ sử dụng sự phản chiếu, nhưng điều đó thực sự khó ngăn trừ khi bạn xây dựng những bộ sưu tập bất biến như những sử dụng trong nhiều ngôn ngữ lập trình hàm, và đó là một câu chuyện khác).
Nếu bạn chỉ trả lại các bộ sưu tập chỉ đọc, bạn nên khai báo thành viên là ReadOnlyCollection<T>
khi một số hành động nhất định thực hiện nhanh hơn (đếm, truy cập các mục theo chỉ mục, sao chép sang bộ sưu tập khác).
Cá nhân tôi muốn xem khuôn khổ bao gồm và sử dụng một giao diện như thế này:
public interface IReadOnlyCollection<T> : IEnumerable<T>
{
T this[int index] { get; }
int Count { get; }
bool Contains(T item);
void CopyTo(T[] array, int arrayIndex);
int IndexOf(T item);
}
Bạn có thể nhận được tất cả các chức năng này sử dụng phương pháp khuyến nông trên đầu trang của IEnumerable<T>
nhưng chúng không phải là performant.
Lưu ý rằng tất cả các loại trên hỗ trợ LINQ với các mức độ khác nhau, hoặc thông qua 'IEnumerable 'hoặc' IQueryable '. –