I am trying to give out a IReadOnly
-references to internal Collection
objects.
This works well in most cases, but does not if i want to convert a dictionary containing a collection into an IReadOnlyDictionary
containing a IReadOnlyCollection
.
Here a code example:
var list = new List<int>();
IReadOnlyList<int> listReference = list; //works;
var dictionary = new Dictionary<int, int>();
IReadOnlyDictionary<int, int> dictionaryReference = dictionary; //works
var nestedList = new List<List<int>>();
IReadOnlyList<IReadOnlyList<int>> nestedReadOnlyListReference = nestedList; //works
var nestedDictionary = new Dictionary<int, List<int>>();
//IReadOnlyDictionary<int, IReadOnlyList<int>> nestedReadOnlyDictionaryReference = nestedDictionary; //does not work, can not implicitly convert
//current workaround
var nestedDictionaryReferenceHelper = new Dictionary<int, IReadOnlyList<int>>();
foreach (var kvpNestedDictionary in nestedDictionary)
{
nestedDictionaryReferenceHelper.Add(kvpNestedDictionary.Key, (IReadOnlyList<int>)kvpNestedDictionary.Value);
}
IReadOnlyDictionary<int, IReadOnlyList<int>> nestedReadOnlyDictionaryReference = nestedDictionaryReferenceHelper; //works, but is only a reference to the internal List, not to the dictionary itself
The workaround is pretty ugly as it needs additional memory and needs manual updating every time the values of nestedDictionary
change.
Is there any simple way to convert such nested dictionaries?
In this SO question you can find a very good explanation why casting dictionary values is not supported. Please see the accepted answer of Eric Lippert.
Although i would not recommend this, you could use the following LINQ expression to cast the values of the dictionary to a read only list:
IReadOnlyDictionary<int, IReadOnlyList<int>> nestedReadOnlyDictionaryReference = nestedDictionary.ToDictionary(kv => kv.Key, kv => kv.Value as IReadOnlyList<int>);
It is a shorter version of your workaround and it is lazy evaluated, but i would not recommend this due to the following reasons:
This is inconsistent behavior and therefore a bad practice!
Unless it is not possible to cast the values of a dictionary, i would not recommend doing this. You should either deep copy the entire dictionary including the nested lists, or use an other container that supports casting.