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.