My question: is there a canonical way of creating a dictionary of dictionaries and providing an outer/inner key pair? Is there a NugetPackage out there with an implementation?
In my code, I have now a few places where I have a property like this
private readonly IDictionary<string, IDictionary<string, SomeType>> _nestedDict =
new Dictionary<string, IDictionary<string, SomeType>>();
and I've created extension methods like this
public static V AddOrUpdate<T, U, V>(
[NotNull] this IDictionary<T, IDictionary<U, V>> dictionary,
[NotNull] T outerKey,
[NotNull] U innerKey,
[NotNull] Func<V> addValueFactory,
[NotNull] Func<V, V> updateValueFactory,
[CanBeNull] IEqualityComparer<U> innerDictionaryComparer = null)
{
IDictionary<U, V> dict;
if (dictionary.TryGetValue(outerKey, out dict))
{
V currentValue;
if (dict.TryGetValue(innerKey, out currentValue))
{
var updatedValue = updateValueFactory(currentValue);
if (!object.ReferenceEquals(updatedValue, currentValue))
dict[innerKey] = updatedValue;
return updatedValue;
}
var addedValue1 = addValueFactory();
dict[innerKey] = addedValue1;
return addedValue1;
}
var addedValue = addValueFactory();
if (innerDictionaryComparer != null)
dictionary[outerKey] = new Dictionary<U, V>(innerDictionaryComparer) {{innerKey, addedValue}};
else
dictionary[outerKey] = new Dictionary<U, V> {{innerKey, addedValue}};
return addedValue;
}
This is powerful, but I'm starting to feel like I should just make a class for nested dictionaries. Here's my thinking:
- The
addValueFactory
andupdateValueFactory
are sort of clumsy and it feels like it's breaking OO principles. - I am thinking about creating a
ConcurrentDictionary
ofDictionary
s (or perhaps ofConcurrentDictionary
s), and this would require some more extension methods. I sort of thought if I'm using it this much that I should just create the darn class and be done with it.
What say you?
Best Answer
There may be a simpler way towards it.
Consider this:
Then you can write:
Now, although it's Visual Studio intellisense-friendly (as you'll notice with automatic code completion proposals after typing the " = " signs in the above assignments), it is arguably a bit cumbersome, still, because of those
and
Which can be alleviated with,
allowing now to write, more simply,
'Hope this helps.