IDictionary<TKey, TValue>
не является ковариантным, ни для TKey, ни для TValue.
Ковариация будет означать, что IDictionary может создавать только типы TKey / TValue, но, поскольку он может производить, а также потреблять их, он не может быть ковариантным или контравариантным в этом отношении.
Я буду определять ковариацию / контравариантность в общих терминах;
IProducer<out T>
является ковариантным, так что это означает, что он производит только T типов. Таким образом, когда вы передаете его ссылке на IProducer с более abstract T, приведение неявно, потому что верно следующее утверждение: «Производитель яблок - это производитель фруктов». (против "Производитель фруктов не обязательно производитель яблок")
IConsumer<in T>
является контравариантным, что означает, что потребляет только T типов. Когда вы передаете ссылку на более конкретный T, приведение неявно, потому что верно следующее утверждение: «Потребитель фруктов - это потребитель яблок». (в отличие от «Потребитель яблок не обязательно является потребителем какого-либо фрукта»)
Что это означает в случае IDictionary, в частности, относительно TValue здесь:
У IDictionary есть методы, которые производят TValues, а также методы, которые используют TValues. Это, как говорится, означает, что оно не было (и не могло) быть объявлено ни ковариантным, ни контравариантным. (см. http://msdn.microsoft.com/en-us/library/s4ys34ea.aspx - в определении общего интерфейса нет «out» или «in»)
Это означает, что когда вы пытаетесь неявно привести ваше Dictionary<uint, List<string>>
в IDictionary<uint, IEnumerable<string>>
, компилятор говорит: «Подождите, созданный вами объект может принять List<string>
только в методе Add, но вы помещаете это в качестве ссылки, которая разрешит любое IEnumerable<string>
in, которое является большим подмножеством. Если вы добавите что-либо, что является IEnumerable<string>
, но не является List<string>
, это не будет работать. " Он не позволяет (и не может) это косвенно допускать, поэтому вам нужен хард-каст.
(спасибо mquander за конкретный пример)