A better way of doing this would be to have a dictionary of dictionaries:
Dictionary<Tuple<Guid, Guid>, Dictionary<Guid, string>> dictionary;
And then have extension methods for the sake of simplifying the code where you use it:
public static bool TryGetValue<TKey1, TKey2, TKey3, TValue>(this Dictionary<Tuple<TKey1, TKey2>, Dictionary<TKey3, TValue>> dict, TKey1 key1, TKey2 key2, TKey3 key3, out TValue value)
{
if (dict.TryGetValue(new Tuple<TKey1, TKey2>(key1, key2), out var subDict) && subDict.TryGetValue(key3, out value))
{
return true;
}
value = default(TValue);
return false;
}
public static bool Add<TKey1, TKey2, TKey3, TValue>(this Dictionary<Tuple<TKey1, TKey2>, Dictionary<TKey3, TValue>> dict, TKey1 key1, TKey2 key2, TKey3 key3, TValue value)
{
var mainKey = new Tuple<TKey1, TKey2>(key1, key2);
if (!dict.TryGetValue(mainKey, out var subDict))
{
subDict = new Dictionary<TKey3, TValue>();
dict[mainKey] = subDict;
}
subDict.Add(key3, value);
}
So when you insert into the dictionary, you use the extension method like this:
dictionary.Add(g1, g2, g3, v1);
and then to get a value:
if (dictionary.TryGetValue(g1, g2, g3, out v1))
{
}
Of course, the key of the outer dictionary is up to you. I just used Tuple
to illustrate how everything can remain strongly typed.