Recipe4.9.Making Read-Only Collections the Generic Way


Recipe 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.



C# Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2004
Pages: 424

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net