What Is ReadOnlyCollection In .Net 4.5?


As you know, the new interfaces  IReadOnlyCollection<T>, IReadOnlyDictionary<T>  and IReadOnlyList<T>  had been added to DotNet4.5. The purpose of these interfaces is providing the generic read-only collection. For that purpose, the DotNet framework also provided the implementation of these interfaces: the  ReadOnlyCollection<T> was inherited IReadOnlyList<T> , and ReadOnlyDictionary<T>  was inherited IReadOnlyDictionary<T>.

The IReadOnlyList<T>  is just an additional that inherited from IReadOnlyCollection<T>  with indexing added.


What is different between Array and ReadOnlyList?

As of now, may you have a question that why do we need these type when we already have Array? However, the purpose of these types already tells via the name. They will provide a read-only collection of item T that is not allowed to add a new item or replace the existing with the other one. As the following code, we will show you the difference between Array and ReadOnlyCollection.


What is difference List<T>.AsReadOnly()  and List<T>.ToArray() ?

Let’s create the huge list of M items.

So what happens when we call list.ToArray()? the framework will create an array with exactly the same size with the list and copy all items in the list to that array by looping on each item of the collection. This behavior quite expensive when working on a huge list.

However, when calling list.AsReadOnly(). It will create the new instance of ReadOnlyCollection and pass the current list into that instance without any loop.


What ReadOnlyCollection does when passing a list as constructor parameter?

Review a part of ReadOnlyCollection’s implementation below, we understand exactly what ReadOnlyCollection does with the passing list. The ReadOnlyCollection just wrapped the passing list inside instead of copied every item of the list.

So The ReadOnlyCollection is a wrapper for any collection that implements IList<T> . It does not copy elements from the IList. Instead, it adds a level of indirection that reduces possible changes.

The ReadOnlyDictionary is working the same way for any collection that implements IDictionary<TKey, TValue> .


When should we use ReadOnlyCollection and ReadOnlyDictionary?

This is just an example to answer the question above.

Readonly Collection Sample

Looks at the diagram above shows you that the Configuration management component is sharing the config collections at cross Biz and DAL layers.

As you know Biz and Dal layers can be added in as many as the application required. So how can we warranty that the config collections are consistent in all layers and none of them can modify the sharing configuration collection? In this case, ReadOnlyCollection and ReadOnlyDictionay are useful. So that Configuration management can load the config values from Db, Json file or the other providers and wrap them into a read-only collection accordingly and provide to the consumer components.

The right way to use IReadOnlyCollection

Let’s review the piece of code below. Both properties are returning the IReadOnlyCollection. However, the second property is more dangerous than the first one because the developer can cast it back to the List instance and add the value in without any exception. However, the first property is completely read-only and there is no way to add the value in.

The generic List instance is implemented the IReadOnlyCollection that why we can return the List as IReadOnlyCollection. However, it is not the right way to do so I would recommend using the first property implementation for the IReadOnlyCollection.

This is the extension method to wrap an IEnumerable to the IReadOnlyCollection I had been written in HBD.Framework.  You might want to take a look.

I hope this helps to answer the question why IReadOnlyCollection had been added to .Net 4.5.

Author: Duy Hoang

Leran what, share that

Leave a Reply