In the recent course of developing my IRC.NET library I was hit (quite plainly) by a scenario where I needed to expose an immutable (read-only) version of a generic Dictionary object, and found no immediate solution in the BCL (base class library). Shortly thereafter I had a similar situation, except involving the exposing of a generic HashSet object. Unfortunately, unlike for Collection<T> objects (or in fact anything that implements IList<T>), there are no read-only equivalents of these classes in the BCL, in the manner of ReadOnlyCollection<T> – not even, I may add, in the latest .NET 4.0 Beta 2. Many developers have complained about the lack of a ReadOnlyDictionary class, and a quick Google search should show up several older and more recent blog posts as well as a couple of Microsoft Connect reports on the subject. No news from the guys at Microsoft, unfortunately.
Note: Don’t be fooled by the naive solution of simply casting the collection object to an IEnumerable<T> and exposing that instead – I’ve seen this on more than one occasion in code I’ve viewed. The problem here, in case it isn’t obvious, is that the user can simply cast the IEnumerable<T> back to the mutable collection type and modify that. More often that not, you want to expose more than just an iterator, anyway.
Having racked my mind for a quick and elegant solution to this issue of exposing read-only collection objects, and not being enticed to tarnish an otherwise well-designed library with nasty hacks, I decided that I would implement immutable wrappers around the IDictionary<TKey, TValue>and ISet<T> interfaces. It turned out this in fact only required a minimal amount of effort, yet I was pleased with what I ended up with, and feel that my implementations are complete and well crafted enough to share with the community.
Download the ReadOnlyDictionary<TKey, TValue> class.
Download the ReadOnlySet<T> class.
Suggestions and comments on the design and code are, of course, most welcome.