---
title: "ReadOnlyCollection is not an immutable collection"
description: "In this blog post we discover how we can mutate a `ReadOnlyCollection` to have more or less entries than its original state. Readonly does not mean it is immutable. Also we will check out the `ImmutableArray`."
updated: 2022-04-26
tags: ["ReadOnlyCollection", "ImmutableArray", "C#", "Immutable"]
canonical: "https://steven-giesel.com/blogPost/c20eb758-a611-4f98-9ddf-b9e2b83fcac9/readonlycollection-is-not-an-immutable-collection"
---

# ReadOnlyCollection is not an immutable collection

In this blog post we discover how we can mutate a `ReadOnlyCollection` to have more or less entries than its original state. Readonly does not mean it is immutable. Also we will check out the `ImmutableArray`. 

## Readonly does not mean immutable
The [`ReadOnlyCollection`](https://docs.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.readonlycollection-1?view=net-6.0) which we have since the .NET Framework 2.0 times is a nice way of telling "Here is a collection which you can not change." In terms of implementation it is just a thin layer on top of a collection, which prohibits operations like `Add`, `Remove` or `Clear`. But that does not mean that the underlying elements can't change.

A `ReadOnlyCollection` is **not** an immutable representation, it is basically just a view of a collection or list. That said, if the original list changes so is the `ReadOnlyCollection` as well.

```csharp
var numbers = new List<int> { 1, 2 };
var readOnlyNumbersViaExtension = numbers.AsReadOnly();
var readOnlyNumbers = new ReadOnlyCollection<int>(numbers);

Console.WriteLine($"List count: {numbers.Count}");
Console.WriteLine($"ReadOnlyCollection via extension count: {readOnlyNumbersViaExtension.Count}");
Console.WriteLine($"ReadOnlyCollection via new count: {readOnlyNumbers.Count}");
```

The output is pretty obvious here:
```no-class
List count: 2
ReadOnlyCollection via extension count: 2
ReadOnlyCollection via new count: 2
```

But what if we add a new element to our original list, what is now the output?
```csharp
numbers.Add(3);

Console.WriteLine($"List count: {numbers.Count}");
Console.WriteLine($"ReadOnlyCollection via extension count: {readOnlyNumbersViaExtension.Count}");
Console.WriteLine($"ReadOnlyCollection via new count: {readOnlyNumbers.Count}");
```

And the output is:
```no-class
List count: 3
ReadOnlyCollection via extension count: 3
ReadOnlyCollection via new count: 3
```

Like a database view, also our read only view to our list gets updated. Is this all bad? Of course not, because that has some advantages as well. The most important is, that the underlying operation to create a `ReadOnlyCollection` is super cheap. It can be done in `O(1)` time as there is no allocation involved in the first place.

## Real Immutability
If we want to have real immutability we have to take different types. For example: [`ImmutableArray`](https://docs.microsoft.com/en-us/dotnet/api/system.collections.immutable.immutablearray.create?view=net-6.0#system-collections-immutable-immutablearray-create-1(-0())). If we do the same example as above, we get what we would expect from an immutable type:

```csharp
var numbers = new List<int> { 1, 2 };
var immutableArray = numbers.ToImmutableArray();

Console.WriteLine($"List count: {numbers.Count}");
Console.WriteLine($"ImmutableArray count: {immutableArray.Length}");

numbers.Add(3);

Console.WriteLine($"List count: {numbers.Count}");
Console.WriteLine($"ImmutableArray count: {immutableArray.Length}");
```

Output:
```csharp
List count: 2
ImmutableArray count: 2
List count: 3
ImmutableArray count: 2
```

We can see that the `Length` stays the same. The downside is obvious: We have to copy the whole array from our original list to our immutable array which costs `O(n)`. By the way the same holds true for an [`ImmutableList<T>`](https://docs.microsoft.com/en-us/dotnet/api/system.collections.immutable.immutablelist-1?view=net-6.0).

## Conclusion
`ReadOnlyCollection` as shown are not immutable. They are just a readonly view of a list. You as consumer can't change them but that does not mean that the original creator/owner of the list can't. If you really need the current state which can't change you have to use the `ImmutableArray` or `ImmutableList`. Even big sites like [this](https://www.dotnetperls.com/readonlycollection) get this concept wrong:

> an immutable collection can be used with less copying—we do not need to worry about it being modified. This can make programs simpler and easier to reason about.

The more you know ;)