TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2396 2.71K
День 1980. #ЗаметкиНаПолях
ReadOnly-Коллекция не Является Неизменяемой

Коллекция «только для чтения» не означает, что она не изменяема. Сегодня посмотрим, как можно изменить ReadOnlyCollection.

ReadOnlyCollection, которая существует со времен .NET Framework 2.0, — это хороший способ сообщить: «Вот коллекция, которую вы не можете изменить». С точки зрения реализации это всего лишь оболочка поверх коллекции, которая запрещает такие операции, как добавление, удаление или очистку. Но это не означает, что её элементы не могут изменяться.

ReadOnlyCollection не является неизменяемым представлением, это, по сути, просто представление коллекции или списка. Тем не менее, если исходный список изменится, изменится и 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) времени, поскольку аллокации памяти не требуется.

Если мы хотим иметь реальную неизменяемость, нужно использовать другие типы, например, ImmutableList. Если мы проведём тот же тест, что и выше, мы получим то, что ожидаем от неизменяемого типа:
var immutable = numbers.ToImmutableList();
Console.WriteLine($"List: {numbers.Count}");
Console.WriteLine($"Immutable: {immutable.Count}");

numbers.Add(4);

Console.WriteLine($"List: {numbers.Count}");
Console.WriteLine($"Immutable: {immutable.Count}");

Вывод:
List: 3
Immutable: 3
List: 4
Immutable: 3

Мы видим, что длина остаётся прежней. Недостаток очевиден: нам нужно скопировать все элементы из исходного списка в неизменяемый список за O(n).

Итого
ReadOnly-коллекции не являются неизменяемыми. Это просто представление коллекции, доступное только для чтения. Вы как потребитель не можете их изменить, но это не значит, что изначальный создатель/владелец списка не может этого сделать. Если вам действительно нужно текущее состояние, которое не может измениться, используйте ImmutableArray/ImmutableList или Frozen-коллекции.

Источник: https://steven-giesel.com/blogPost/c20eb758-a611-4f98-9ddf-b9e2b83fcac9/readonlycollection-is-not-an-immutable-collection
  • 👍 40
More from @netdeveloperdiary
  1. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  2. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  3. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  4. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  5. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  6. Oct 3, 2026Post #3360
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →