Why can't Dictionary> be cast to Dictionary>?

前端 未结 3 1315
深忆病人
深忆病人 2021-01-20 21:23

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

相关标签:
3条回答
  • 2021-01-20 22:05

    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
    
    0 讨论(0)
  • 2021-01-20 22:09

    yes, it's an issue with covariance. I believe this was corrected with .net 4.0

    0 讨论(0)
  • 2021-01-20 22:11

    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.

    0 讨论(0)
提交回复
热议问题