C# Generics Recipes—Making Read-Only Collections the Generic Way
Microsoft .NET Framework, ASP.NET, Visual C# (CSharp, C Sharp, C-Sharp) Developer Training, Visual Studio
| CSharp-Online.NET:Articles |
| C# Articles |
| © 2006 O'Reilly Media, Inc. |
Contents |
4.9 Making Read-Only Collections the Generic Way
Problem
You have a collection of information that you want to expose from your class, but you don’t want any users modifying the collection.
Solution
Use the ReadOnlyCollection<T> wrapper to easily support collection classes that cannot be modified. For example, a Lottery class that contained the winning lottery numbers should make the winning numbers accessible, but not allow them to be changed:
public class Lottery { // Make a list. List<int> _numbers = null; public Lottery( ) { // Make the internal list _numbers = new List<int>(5); // Add values _numbers.Add(17); _numbers.Add(21); _numbers.Add(32); _numbers.Add(44); _numbers.Add(58); } public ReadOnlyCollection<int> Results { // Return a wrapped copy of the results. get { return new ReadOnlyCollection<int>(_numbers); } } }
Lottery has an internal List<int> of winning numbers that it fills in the constructor. The interesting part is that it also exposes a property called Results, which returns a ReadOnlyCollection typed as <int> for seeing the winning numbers. Internally, a new ReadOnlyCollection wrapper is created to hold the List<int> that has the numbers in
it, and then this instance is returned for use by the user.
If users then attempt to set a value on the collection, they get a compile error:
Lottery tryYourLuck = new Lottery( ); // Print out the results. for (int i = 0; i < tryYourLuck.Results.Count; i++) { Console.WriteLine("Lottery Number " + i + " is " + tryYourLuck.Results[i]); } // Change it so we win! tryYourLuck.Results[0]=29; //The above line gives // Error 26 // Property or indexer // 'System.Collections.ObjectModel.ReadOnlyCollection<int>.this[int]' // cannot be assigned to -- it is read only
Discussion
The main advantage ReadOnlyCollection provides is the flexibility to use it with any collection that supports IList or IList<T> as an interface. ReadOnlyCollection can be
used to wrap a regular array like this:
int [] items = new int[3]; items[0]=0; items[1]=1; items[2]=2; new ReadOnlyCollection<int>(items);
This provides a way to standardize the read-only properties on classes to make it easier for consumers of the class to recognize which properties are read-only simply by the return type.
See Also
See the "IList" and "Generic IList" topics in the MSDN documentation.
|

