A software developer occasionally may have need for a container class, such as a Hashtable, that can be filled with data in an early phase of a program, but then made read-only (Immutable) for subsequent usage. This cannot be done with properties or member object access modifiers alone. Even if some class provides read-only access to its Hashtable member object, the contents of the Hashtable can still be changed, even if the Hashtable itself cannot be changed.
An Immutable Hashtable is a hybrid Hashtable collection in which:
- The internal member Hashtable is never directly accessible to the user, to prevent them from modifying its contents outside of the interface.
- Items may only be added to the collection via the Add () method, and only until the SetReadOnly () method is called. Once that method is invoked, the Hashtable is immutable.
- Immutability is enforced both by exception throwing and by Debug.Assert tests (since this is a design issue) when the program is run in the debug mode. So if a user attempts to call a method such as Add () after the p_isReadOnlyFlag is true, the ImmutableHash object throws either an assertion error when running in Debug mode, or a InvalidOperationException in Release mode.
.NET does not provide users the ability to make a Hashtable read-only (or to make a read-only copy of a Hashtable, as is the case with ArrayList containers).
Using the code
The ImmutableHash class file can be added directly to a project, or to a dll library project. Users are responsible to change the namespace to something appropriate for their project.
static void Main (string args)
ImmutableHash iht = new ImmutableHash ();
/// Objects can be added to the ImmutableHash
/// iht until it is made read-only:
iht.Add ("apples", 2);
iht.Add ("oranges", 5);
iht.Add ("peaches", 4);
iht.SetReadOnly (); /// Make iht Immutable
iht.Add ("plums", 6); /// will throw an exception
Console.WriteLine ("could not add 'plums' to iht");
Points of Interest
To make this class easier to work with in existing applications, the user can create a regular Hashtable object first, and use all the Hashtable methods and properties of the created object; then pass this object to the ImmutableHash when the ImmutableHash is created. Once the SetReadOnly () method is called, the hashtable object cannot be further modified from the ImmutableHash interface.
Other methods native to the inner hashtable can be exposed in the ImmutableHash interface if desired. However, it is important to understand that one should never return the inner hashtable object itself, as this would defeat the purpose of this class.