Почему не словарь> быть брошенным в словарь>? - PullRequest
3 голосов
/ 05 января 2012

Мне интересно, почему я не могу просто разыграть (у меня есть смутное представление, что это может иметь какое-то отношение к тому, что связано с контравариантностью?), И я вынужден копировать элементы первого словаря в новый один, чтобы получить тип, который я хочу?

Ответы [ 3 ]

10 голосов
/ 05 января 2012

Вы не можете сделать это, потому что они не одного типа. Рассмотрим:

        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];

Имеет ли это смысл? Потому что Dictionary<string, List<int>> говорит, что TValue равно List<int>, что означает, что вы можете Add() a List<int> в качестве значения. Если бы вы могли привести это значение к Dictionary<string, IEnumerable<int>>, это означало бы, что тип значения равен IEnumerable<int>, что означает, что вы могли бы Add() любой IEnumerable<int> (int[], HashSet<int> и т. Д.), Которые нарушают исходный тип.

Таким образом, List<T> можно преобразовать в ссылку IEnumerable<T>, поскольку List<T> реализует IEnumerable<T>, но это не означает, что Dictionary<TKey, List<TValue>> реализует / расширяет Dictionary<TKey, IEnumerable<TValue>>.

Проще говоря:

Dictionary<int, Dog> 

Невозможно преобразовать в

Dictionary<int, Animal>

Потому что последний позволит вам добавить Кошку, Белку и т. Д.

1 голос
/ 05 января 2012

Вы не можете разыграть, потому что это по-прежнему Dictionary<T1, List<T2>>

Допустим,

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 голосов
/ 05 января 2012

да, это проблема с ковариацией.Я считаю, что это было исправлено с помощью .net 4.0

...