Коллекция «только для чтения» не означает, что она неизменяема. Сегодня посмотрим, как можно её изменить.
ReadOnlyCollection — это хороший способ сообщить, что эта коллекция, которую вы не можете изменить. Однако, с точки зрения реализации, это всего лишь оболочка поверх коллекции, которая запрещает такие операции, как добавление, удаление или очистку. Это не означает, что её элементы не могут изменяться.
Приведу пример, результат которого будет довольно очевиден:
var numbers = new List<int> { 1, 2 };
var asReadOnly = numbers.AsReadOnly();
var readOnly = new ReadOnlyCollection<int>(numbers);
Console.WriteLine($"List: {numbers.Count}");
Console.WriteLine($"AsReadOnly: {asReadOnly.Count}");
Console.WriteLine($"ReadOnly: {readOnly.Count}");
// Очевидный вывод:
// List: 2
// AsReadOnly: 2
// ReadOnly: 2
Но что, если мы добавим элемент в исходный список?
numbers.Add(3);
Теперь вывод в консоль будет следующим:
List: 3
AsReadOnly: 3
ReadOnly: 3
Как и представление в базе данных, наше представление списка «только для чтения» обновляется. Это плохо? Нет, потому что имеет некоторые преимущества. Самое главное — базовая операция по созданию ReadOnlyCollection очень бюджетная. Она занимает O(1) времени, поскольку аллокация памяти не требуется.
Чтобы иметь реальную неизменяемость (immutable), нужно использовать другие типы, например, ImmutableList.
Если мы проведём тот же тест, что и выше, мы получим то, что ожидаем от неизменяемого типа:
var numbers = new List<int> { 1, 2 };
var immutable = numbers.ToImmutableList();
Console.WriteLine($"List: {numbers.Count}");
Console.WriteLine($"Immutable: {immutable.Count}");
numbers.Add(3);
Console.WriteLine($"List: {numbers.Count}");
Console.WriteLine($"Immutable: {immutable.Count}");
// Вывод:
// List: 2
// Immutable: 2
// List: 3
// Immutable: 2
Мы видим, что длина остаётся прежней. Недостаток в том, что нам нужно скопировать все элементы из исходного списка в неизменяемый список за O(n).
ReadOnlyCollection не является неизменяемым. Это просто представление коллекции, доступное только для чтения. Вы, как потребитель, не можете их изменить, но это не значит, что изначальный создатель/владелец списка не может этого сделать. Если вам действительно нужно текущее состояние, которое не может измениться, используйте ImmutableArray или ImmutableList.
#Полезно #Immutable #ReadOnlyCollection #Array
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤1