ReadOnlyList and runtime errors

Compile vs runtime error occurs with readonly lists

Home DailyDrop

Daily Knowledge Drop

When working with a ReadOnlyList, depending on how the list is defined, it is possible to accidentally try change a value in the list, with the exception only becoming apparent at runtime and not compile time.


Runtime

Suppose we have the following code:

List<int> golden = new List<int> { 1, 6, 1, 8 };

// readonlyGolden is a readonly list
IList<int> readonlyGolden = golden.AsReadOnly();

// still allows for trying to change the value
readonlyGolden[1] = 7;

Even though golden is being converted to readonly list with the AsReadOnly method, as it is being cast to IList<int>, the compiler does recognize readonlyGolden are read only.

"Changing" the value in the readonly list is "allowed" at compiled, however at runtime a NotSupportedException will be thrown:

Collection is read-only.

Compile time

Instead, of IList<int> the golden variable is cast to IReadOnlyList<int>:

List<int> golden = new List<int> { 1, 6, 1, 8 };

// readonlyGolden is a readonly list
IReadOnlyList<int> readonlyGolden = golden.AsReadOnly();
// OR
// IReadOnlyList<int> readonlyGolden = golden

// this will cause a compiler error
readonlyGolden[1] = 7;

Now the code will not compile, as the compile recognizes readonlyGolden as read-only.

Property or indexer 'IReadOnlyList<int>.this[int]' cannot be assigned to -- it is read only

Notes

The above may seem obvious - cast a list to IList and it's not (necessarily) readonly, while casting it to IReadOnlyList will definitely make it readonly. However, the take away is that one cannot assume that an IList is mutable, just because the compiler does not stop the code from compiling - the implementation could be a ReadOnlyList, which will only become apparent at runtime, with an exception.


References

Davide Bellone tweet

Daily Drop 179: 11-10-2022

At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.

The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.
c# .net list readonly