DotNetCurry Logo

Read Only Dictionary in .NET 4.5

Posted by: Sumit Maitra , on 1/25/2014, in Category .NET Framework
Views: 51908
Abstract: The ReadOnlyDictionary generic type in .NET 4.5 fulfills a long standing feature request for the BCL. It is useful for scenarios where read only Dictionaries need to be exposed. One such case is shown in this article.

Yes! For people doing custom implementation to create a Read Only Dictionary, there is now a .NET BCL implementation of the same in .NET 4.5.

Why do you need a ReadOnlyDictionary in the first place?

A ReadOnlyDictionary is a useful data container when you are sending data across layers of an application and you want to ensure the data is not modified across the layer.

A good use case for this is Configuration information that is critical for functioning of an application. We may want multiple layers of the application to have access to the configuration information (and a dictionary is a very good way to pass configuration around) but no one should be able to update the configuration directly,- without going through the required checks and balances. In the following sample, we will create a small example.

 

 

A Read-only Configuration

Step 1: Create a new Console Application in Visual Studio 2012 CP. Name the Solution ‘ReadOnlyCollectionSample’.

Step 2: Add two Window Class Library projects, ConfigurationLibrary and ConfigurationConsumer.

Step 3: In the ConfigurationLibrary project, add a Class called ConfigurationContainer

solution-structure

Step 4: Setting up the ConfigurationContainer

- In the ConfigurationContainer, add a field _mutableConfiguration for type Dictionary<string, string>. This is where we will load our configuration.

- In the constructor, initialize the _mutableConfiguration dictionary and add some key value pairs to it.

- Add a property called Configuration with the type ReadOnlyDictionary<string, string> with a getter only. The Getter will return a new instance of ReadOnlyDictionary<string, string>. The Read Only Dictionary is initiated using the _mutableConfiguration.

- Add a public method AddToConfiguration(key, value). This method will add/update a configuration key/value pairs from outside.

- Add a method ConfigurationAllowed that returns a Boolean. This contains the logic that decides if a particular configuration parameter can be updated or not and update it accordingly. Essentially we have restricted users from updated the Configuration and we will be controlling the update via this method.

- The final class looks as follows:

configuration-container

Step 5: Setting up the ConfigurationConsumer

- Rename the Class1 to ConfigurationConsumer

- Declare a field of type IReadOnlyDictionary<string, string> called _config.

- In the Constructor initialize the _config field by using the Configuration property of an instance of ConfigurationContainer

- Add a method DoSomething() that checks if a “key” called configuration exists and prints a message with the value if it does. If the “key” does not exist it prints a different message.

- Add another method called BeNaughtyWithConfiguration(). Try to cast the _config read-only dictionary into an ordinary IDictionary. Now add a key to the IDictionary instance. The full listing is as follows

configuration-consumer

Step 6: Using the Configuration in ReadOnlyCollectionSample

- In the Program.cs’ main method instantiate the ConfigurationConsumer and call the DoSomething() method

- Add a Console.ReadLine() to wait for user input before executing the next line.

- Call the BeNaughtyWithConfiguration() method

- The Final code is as follows

program-main-method

Running the Sample

Build and run the sample. The output on the console will be something as follows:

 console-output-1

As we see, the value from the Read only dictionary was extracted successfully.

Next we hit enter and the code tries to execute the BeNaughtyWithConfiguration method. Wham! We get the following exception:

  not-supported-exception

As we can see, our ReadOnly configurations are safe from type conversion into updatable counterparts.

If you add a watch for the convertToReadWrite.IsReadOnly property, you will find it to be ‘True’.

watch-isreadonly-true

A Note about Dictionary of Mutable Objects

In our above sample, the Dictionary was that of primitive type ‘string’ that is itself immutable. However if you had a read only dictionary of type say ConfigElement, where ConfigElement is defined as follows:

config-element

The ReadOnlyDictionary in this case would not be able to prevent changes to the ConfigElement instance. So if someone retrieved the ConfigElement from the readonly dictionary and updated the Value property, the property would get change in the instance that’s in the Dictionary.

updating-mutable-objects

This code will give us the following output

updated-mutable-objects

As we can see the element got updated in the Dictionary.

Conclusion

To conclude, the new ReadOnlyDictionary<T,T> generic type in .NET 4.5 fulfills a long standing feature request for the BCL. It will be very useful for scenarios where read only Dictionaries need to be exposed. One such case is shown above.

Download the entire code (including use of the ConfigElement type) from here (Github)

Note: We have tested the code on the following combinations : VS 2012 + Windows 7 & Windows 8

Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+
Further Reading - Articles You May Like!
Author
Sumit is a .NET consultant and has been working on Microsoft Technologies since his college days. He edits, he codes and he manages content when at work. C# is his first love, but he is often seen flirting with Java and Objective C. You can follow him on twitter at @sumitkm or email him at sumitkm [at] gmail


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Ron on Wednesday, November 19, 2014 2:03 PM
Excellent post.  Just wondering if you could answer this.  Is it really necessary to have a private ReadOnlyDictionary and have the public getter set that member and then return it?  As long as we're always returning a new ReadOnlyDictionary from that getter, can't we just do this?

get
{
    return new ReadOnlyDictionary<string, string>(_mutableConfiguration);
}