Список <T>.AsReadOnly() vs IReadOnlyCollection <T>
List<T>
реализует интерфейс IReadOnlyCollection<T>
и предоставляет метод AsReadOnly()
, который возвращает ReadOnlyCollection<T>
(который, в свою очередь, реализует IReadOnlyCollection<T>
).
Каково использование/причина для AsReadyOnly()
? Его существование пахнет одним или двумя краевыми случаями, когда просто вернуть список как IReadOnlyCollection<T>
просто недостаточно.
Сначала, хотя это может быть связано с тем, чтобы избежать извлечения стоимости, но похоже, что вы можете сделать это с помощью ReadOnlyCollection<T>
Items
accessor.
BTW. Документация для типа ReadOnlyCollection<T>
читает
Предоставляет базовый класс для общей коллекции только для чтения.
который в моей голове конфликтует с конструктором, описанным как
Инициализирует новый экземпляр класса (...), который является оболочкой только для чтения вокруг указанного списка.
Update:
Я не видел, что ReadOnlyCollection<T>
Items
защищен.
Ответы
Ответ 1
Если вы просто вернете фактический List<T>
как IReadOnlyList<T>
, тогда вызывающий может всегда просто отбрасывать его, а затем изменять список по своему усмотрению. И наоборот, вызов AsReadOnly()
создает оболочку списка только для чтения, которую пользователи не могут обновить.
Обратите внимание, что оболочка, предназначенная только для чтения, будет отражать изменения, внесенные в базовый список, поэтому код с доступом к исходному списку может обновить его с учетом того, что все пользователи версии только для чтения увидят эти изменения.
Ответ 2
Прежде всего, это не то, что AsReadOnly()
был добавлен, потому что IReadOnlyList<T>
недостаточно хорош - IReadOnlyList<T>
доступен только начиная с .NET 4.5, а метод AsReadOnly()
существует с .NET 2.
Более важно: AsReadOnly()
и IReadOnlyList<T>
служат в самых разных целях.
ReadOnlyCollection<T>
предназначен для реализации объектных моделей, например таких, как Dictionary<K,V>.Keys
и Dictionary<K,V>.Values
. Это касается сценариев, в которых потребители не могут изменять содержимое, пока производитель может. Он работает в тандеме с Collection<T>
, который позволяет владельцам проверять изменения или выполнять побочные эффекты при добавлении элементов.
IReadOnlyList<T>
С другой стороны, это просто интерфейс, который обеспечивает просмотр коллекции только для чтения. Методы могут использовать его, чтобы сказать: "Мне нужна коллекция с произвольным доступом, но мне не нужно ее модифицировать". Например, метод BinarySearch
может выглядеть так:
public int BinarySearch<T>(IReadOnlyList<T> list, int start, int length);
Чтобы сделать этот метод полезным, он должен иметь возможность проходить в любом Списке. Принудительное создание коллекций обложек было бы чрезмерно дорогостоящим.