Introduction
A software developer occasionally may have need for a container class, such as an ArrayList, 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 ArrayList member object, the contents of the ArrayList can still be changed, even if the ArrayList itself cannot be changed.
An Immutable ArrayList is a hybrid ArrayList container in which:
- The internal member ArrayList is never directly accessible to the users, 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 ArrayList 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 ImmutableArrayList object throws either an assertion error when running in Debug mode, or a InvalidOperationException in Release mode.
Download ImmutableArrayListTest.zip - 8.3 KB
Background
.NET provides the ability to make a read-only COPY of an ArrayList with the following construct:
ArrayList myAL = new ArrayList ();
...
ArrayList myReadOnlyAL = ArrayList.ReadOnly (myAL)
But now you have two objects to manage and you had to pay for making a new copy of an already existing Container. With an ImmutableArrayList class, you still only have one container object as you are not making any extra copies of it. The ImmutableArrayList class essentially functions as a read-only interface wrapper for an ArrayList. Plus, you can tweak its interface to suit your needs (maybe you want to make the ReadOnly flag reversable under certain conditions).
Using the code
The ImmutableArrayList 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.
using System;
using System.Threading;
namespace ImmutableArrayListTest
{
class Program
{
static void Main (string[] args)
{
ImmutableArrayList ial = new ImmutableArrayList ();
ial.Add ("apples");
ial.Add ("oranges");
ial.Add ("peaches");
ial.SetReadOnly ();
try
{
ial.Add ("plums");
}
catch
{
Console.WriteLine ("could not add 'plums' to ial");
Thread.Sleep (5000);
}
}
}
}
Points of Interest
To make this class easier to work with in existing applications, the user can create a regular ArrayList object first, and use all the ArrayList methods and properties of the created object; then pass this object to the ImmutableArrayList when the ImmutableArrayList is created. Once the SetReadOnly () method is called, the contents of the inner member ArrayList object cannot be further modified from the ImmutableArrayList interface.
Other methods native to the inner member ArrayList can be exposed in the ImmutableArrayList interface if desired. However, it is important to understand that one should never return the inner ArrayList object itself, as this would defeat the purpose of this class.
History
Initial version.