C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
With this type from System.Collections.ObjectModel, we provide a collection of elements that cannot be changed. But it may be possible to change some elements themselves.
Example. In this program, a list of ints is created, and then the ReadOnlyCollection constructor is used with that List as an argument. Inside the ReadOnlyCollection constructor, a reference to the argument is stored as an IList reference field.
Tip: In the ReadOnlyCollection constructor, no elements are copied. The constructor is fast.
C# program that uses ReadOnlyCollection
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
class Program
{
static void Main()
{
List<int> list = new List<int>();
list.Add(1);
list.Add(3);
list.Add(5);
// Constructor.
ReadOnlyCollection<int> read = new ReadOnlyCollection<int>(list);
// Loop over ReadOnlyCollection.
foreach (int value in read)
{
Console.WriteLine("read: {0}", value);
}
// Copy ReadOnlyCollection to an array.
int[] array = new int[3];
read.CopyTo(array, 0);
// Display array.
foreach (int value in array)
{
Console.WriteLine("array: {0}", value);
}
// Use methods on ReadOnlyCollection.
int count = read.Count;
bool contains = read.Contains(-1);
int index = read.IndexOf(3);
Console.WriteLine("{0}, {1}, {2}", count, contains, index);
}
}
Output
read: 1
read: 3
read: 5
array: 1
array: 3
array: 5
3, False, 1


You can loop over the ReadOnlyCollection using the foreach-loop. A for-loop is also possible with the Count property and indexer. CopyTo provides a way to copy the elements to an array. You must allocate the array yourself.
Finally: We see the Count, Contains, and IndexOf methods. These have the same functionality as the equivalent methods on the List type.
Example 2. With ReadOnlyCollection, the collection itself is read-only. This means that if you have a ReadOnlyCollection(int), nothing can be changed. Ints are value types. Changing an int in the collection would change the collection itself.
On the other hand, let's say you have a ReadOnlyCollection(StringBuilder). This is kind of a strange thing to have, but it is acceptable. You can still change the individual StringBuilder objects by accessing their methods.
Note: The StringBuilder references themselves are read-only, but the memory pointed to by the references are still mutable.
C# program that changes object in ReadOnlyCollection
using System;
using System.Collections.ObjectModel;
using System.Text;
class Program
{
static void Main()
{
// Set up the ReadOnlyCollection.
StringBuilder[] array = new StringBuilder[1];
array[0] = new StringBuilder();
var read = new ReadOnlyCollection<StringBuilder>(array);
// Now we change an object pointed to in a ReadOnlyCollection.
read[0].Append("Dot").Append("Net").Append("Perls");
Console.WriteLine(read[0]);
}
}
Output
DotNetPerls


Tip: Read-only status is not transferred to other references. The StringBuilder references are completely normal ones.
But: You cannot replace the references with other StringBuilder references or the null literal.
Summary. The ReadOnlyCollection in the System.Collections.ObjectModel namespace functions as a wrapper for any collection that implements IList(T). It does not copy elements. Instead it adds a level of indirection that reduces possible changes.