я просто совершенно не понимаю контравариантность?
Да. Вы совершенно и совершенно не поняли, что означают «ковариация» и «контравариантность» . Вы перепутали их с совместимостью назначений .
Это очень распространенная ошибка. Эти два понятия взаимосвязаны, но они совсем не совпадают .
Совместимость присваиваний - это свойство, что выражение одного типа может храниться в переменной другого типа.
Ковариация - это свойство, при котором сопоставление типов с типами сохраняет совместимость назначения направления. Если Giraffe совместим с присвоением с Animal, и это означает, что IEnumerable<Giraffe>
совместимо с назначением с IEnumerable<Animal>
, тогда отображение IEnumerable<T>
является ковариантным .
См. Мою статью на эту тему для более подробной информации:
http://blogs.msdn.com/b/ericlippert/archive/2009/11/30/what-s-the-difference-between-covariance-and-assignment-compatibility.aspx
Работает установка a в B, что является ковариацией
Да, это работает. «a» совместимо с присвоением с B. Это не «ковариация», потому что ничего не меняется . Нет сопоставления типов с типами , которое сохраняет направление совместимости назначения, используемое в назначении "a = B"; нет ничего общего.
, но установка b на новый A завершается ошибкой компиляции.
Correct.
Есть ли способ сделать это?
Нет. Вместо «А» и «В» назовите их «Животное» и «Жираф». Каждый Жираф - Животное, поэтому если переменная может содержать Животное, то оно может содержать Жирафа. Если вы попытаетесь пойти другим путем, вы не сможете поместить Animal в переменную типа Giraffe. Животное на самом деле может быть тигром. Почему вам следует разрешить помещать тигра в переменную типа Giraffe?