Now if you try to modify the readOnlyStrings collection, you can’t. Because it is read only. But what about modifying strings collection which is of type List<T>. Well you should be able to modify it for example by adding a new item.

strings.Add("Visual Studio 2015");

Now let’s see what do we have on the readOnlyStrings collection.

foreach (string item in readOnlyStrings)

{

Console.WriteLine(item);

}

Result

Surprisingly you will see that your readOnlyStrings collection has been modified. But did you add an item to readOnlyStrings, No, but you did add an item to strings.

So what happened here is nicely described on MSDN.

“An instance of the ReadOnlyCollection<T> generic class is always read-only. A collection that is read-only is simply a collection with a wrapper that prevents modifying the collection; therefore, if changes are made to the underlying collection, the read-only collection reflects those changes.”

Now let’s take another scenario.

Here I have a simple class named VisualStudio and there I have a helper method which will return new instance of List<VisualStudio>.

Now let’s try to modify an item in the readOnlyVisualStudios and see the content of readOnlyVisualStudios.

readOnlyVisualStudios[0].Name = "Microsoft Visual Studio 2010";

foreach (VisualStudio item in readOnlyVisualStudios)

{

Console.WriteLine(item.Name);

}

Result

Again it seems readOnlyVisualStudios has been modified. This shows another feature of ReadOnlyCollection<T>. That is when the T in ReadOnlyCollection<T> is a complex type, the individual items of ReadOnlyCollection<T> can be modified either by changing the values of it’s properties or by calling the methods of complex type. But the following is illegal and will throw an error.

So that’s it. Keep in mind that when working with ReadOnlyCollection<T>, you need to make sure, you are not letting the underline collection to be modified or only let the class that contains the underline collection to modify it and not others for instance like below.

private List<string> strings;

public ReadOnlyCollection<string> Strings

{

get { returnnew ReadOnlyCollection<string>(strings); }

}

If you want your strings which is of List<T> to be read only, make it private so you (containing class) can do what ever you want and expose as a public ReadOnlyCollection<T> to consumers.