For example, let’s take following List of type string.
List<string> strings = new List<string>()
{
"Visual Studio 2010","Visual Studio 2012","Visual Studio 2013"
};
So basically there is two ways that I can create a
ReadOnlyCollection<T> from this.
ReadOnlyCollection<string> readOnlyStrings = strings.AsReadOnly();
// or
ReadOnlyCollection<string> readOnlyStrings = new ReadOnlyCollection<string>(strings);
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>.
class VisualStudio
{
public string Version { get; set; }
public static List<VisualStudio> GetVisualStudios()
{
return new List<VisualStudio>()
{
new VisualStudio() { Version = "Visual Studio 2010" },
new VisualStudio() { Version = "Visual Studio 2012" },
new VisualStudio() { Version = "Visual Studio 2013" },
};
}
}
ReadOnlyCollection<VisualStudio> readOnlyVisualStudios = new ReadOnlyCollection<VisualStudio>(VisualStudio.GetVisualStudios());
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.
readOnlyVisualStudios[0] = null;
// or
readOnlyVisualStudios[0] = new VisualStudio() { Name = "Microsoft Visual Studio 2010" };
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 { return new 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.
Hope this helps.
Happy Coding.
Regards,
Jaliya