Почему я могу отказаться от инвариантности IList ?

В настоящее время я готовлю презентацию новых универсальных функций дисперсии в C # для моих коллег. Короче говоря, я написал следующие строки:

IList<Form> formsList = new List<Form> { new Form(), new Form() };
IList<Control> controlsList = formsList;

Да, это, конечно, невозможно, поскольку IList (Of T) инвариантен (по крайней мере, моя мысль). Компилятор сообщает мне, что:

Невозможно неявно преобразовать тип System.Collections.Generic.IList в System .Collections.Generic.IList . Существует явное преобразование (не хватает ли приведения?)

Хм, значит ли это, что я могу принудительно выполнить явное преобразование? Я только что попробовал:

IList<Form> formsList = new List<Form> { new Form(), new Form() };
IList<Control> controlsList = (IList<Control>)formsList;

И… он компилируется! Значит ли это, что я могу отбросить инвариантность? - По крайней мере, с компилятором все в порядке, но я просто превратил бывшую ошибку времени компиляции в ошибку времени выполнения:

Невозможно преобразовать объект типа 'System.Collections.Generic.List`1 [System.Windows.Forms .Form] », чтобы ввести« System.Collections.Generic.IList`1 [System.Windows.Forms.Control] ».

Мой вопрос (ы): Почему я могу отказаться от инвариантности IList (или любого другого инвариантного интерфейса относительно моих экспериментов)? Действительно ли я отбрасываю инвариантность, или какое преобразование здесь происходит (поскольку IList (Of Form) и IList (Of Control) совершенно не связаны)? Это темный уголок C #, которого я не знал?

5
задан Yuval Itzchakov 21 November 2014 в 13:53
поделиться