I\'m wondering why I can\'t just cast (I have a vague idea this might have something to do with that co/contravariance stuff?), and am I forced to copy the elements of the f
You can not cast, because it still is a Dictionary<T1, List<T2>>
Lets say
Dictionary<string, List<int>> d1 = new Dictionary<string, List<int>>();
Dictionary<string, IEnumerable<int>> d2 = (Dictionary<string, IEnumerable<int>>)d1; // this is the invalid cast
d2["one"] = new int[0]; // valid for d2
List<int> list1 = d1["one"]; // would fail
yes, it's an issue with covariance. I believe this was corrected with .net 4.0
You cannot do this because they aren't the same type. Consider:
var x = new Dictionary<string, List<int>>();
// won't compile, but assume it could...
Dictionary<string, IEnumerable<int>> xPrime = x;
// uh oh, would allow us to legally add array of int!
xPrime["Hi"] = new int[13];
Does this make sense? Because Dictionary<string, List<int>>
says the TValue
is List<int>
which means you can Add()
a List<int>
as a value. If you could cast this to a Dictionary<string, IEnumerable<int>>
it would mean the value type is IEnumerable<int>
which would mean you could Add()
any IEnumerable<int>
(int[]
, HashSet<int>
, etc) which would violate the original type.
So, a List<T>
can be converted to a IEnumerable<T>
reference because List<T>
implements IEnumerable<T>
, but that does not mean that Dictionary<TKey, List<TValue>>
implements/extends Dictionary<TKey, IEnumerable<TValue>>
.
Put more simply:
Dictionary<int, Dog>
Can't convert to
Dictionary<int, Animal>
Because the latter would allow you to add Cat, Squirrel, etc.