Constructing immutable dictionary with inner immutable dictionary

1.6k views Asked by At

I have the following dictionary and wish to make it immutable;

var dict = ConcurrentDictionary<Type, ConcurrentDictionary<Type, Action>>

I then call

var immmutableDict = dict.ToImmutableDictionary();

However this would still give the internal ConcurrentDictionary<Type, Action> dictionary i believe.

How can i make an immutable copy of the entire dictionary in a thread safe fashion with existing functions, or would i need to lock the entire operation to ensure atomic conversion?

ImmutableDictionary<Type, ImmutableDictionary<Type, Action>>

Alternatively if the above is not possible, i can refactor code to use an ReadOnlyDictionary dictionary from the start, however i face the same challenge with the inner dictionary to make it read only during construction:

var dict2 = new Dictionary<Type, Dictionary<Type, InstanceProducer>>();
/* snip perform adds to above dictionary to initialise state */

var immutableDict = dict2.ReadOnlyDictionary(); // ????
// where ReadOnlyDictionary<Type, ReadOnlyDictionary<Type, InstanceProducer>>(); is returned
// i need to make the above immutable with an immutable internal dictionary
2

There are 2 answers

0
StriplingWarrior On BEST ANSWER

You just need to convert each of the internal dictionaries into immutable dictionaries as well, and then make a new ImmutableDictionary from those.

ImmutableDictionary<Type, ImmutableDictionary<Type, Action>> immutableDict = dict
    .ToImmutableDictionary(e => e.Key, e => e.Value.ToImmutableDictionary());
2
Arsen Khachaturyan On

However this would still give the internal ConcurrentDictionary<Type, Action> dictionary i believe.

Calling:

var immmutableDict = dict.ToImmutableDictionary();

will result of creating a type: ImutableDictionary<Type, ConcurrentDictionary<Type, Action>, so it will not be the ConcurrentDictionary.

How can i make an immutable copy of the entire dictionary in a thread safe fashion with existing functions, or would i need to lock the entire operation to ensure atomic conversion?

To understand how dict.ToImmutableDictionary() works lets read the official documentation, which says:

Enumerates a sequence of key/value pairs and produces an immutable dictionary of its contents.

Does this thread-safe? Yes, because ImmutableDictionary is a thread-safe and creating one from ConcurrentDictionary should also be thread-safe.

However, it's worth asking yourself another question:

  • Why could I need this?

The reason for this question is the word Immutable, which means that it will create a new instance of the data each time when the modification will happen.

Taking into account that multi-threading means multiple thread access for possibly changing the data (unless you know that it will not be changed), it can become a really big performance hit.