Why can I discard the invariance of IList <T>?

I am currently preparing a presentation of new common variance features in C # for my colleagues. In short, I wrote the following lines:

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

Yes, this, of course, is impossible, since IList (Of T) is invariant (at least in my mind). The compiler tells me that:

Cannot implicitly convert type System.Collections.Generic.IList<System.Windows.Forms.Form>to System.Collections.Generic.IList<System.Windows.Forms.Control>. there is an explicit conversion (do you miss the role?)

Hm, does this mean that I can force an explicit conversion? I just tried:

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

And ... it compiles! Does this mean that I can drop immutability? - At least the compiler is fine with this, but I just turned the former compile-time error into a runtime error:

Unable to cast object of type 'System.Collections.Generic.List`1[System.Windows.Forms.Form]' to type 'System.Collections.Generic.IList`1[System.Windows.Forms.Control]'.

(): IList<T> ( )? ( IList(Of Form) IList(Of Control) )? #, ?

+5
2

, IList<Control>, IList<Form>, , ( : , . , , ).

:

public class EvilList : IList<Form>, IList<Control> { ... }

, CLR. , , .

, :

castclass [mscorlib]System.Collections.Generic.IList`1<class [System.Windows.Forms]System.Windows.Forms.Control>

MSDN:

castclass ( O) . , . (, ) , InvalidCastException. , castclass .

InvalidCastException , obj .

+6

, , TextBlock . TextBlock controlList, formList.

IList<Form> formsList = new List<Form> { new Form(), new Form() }; 
IList<Control> controlsList = (IList<Control>)formsList; 
controlsList.Add(New TextBlock); // Should throw at runtime.

. controlList IEnumerable, IList ( .Net 4.0), IEnumerable (IEnumerable). , .Add( ) .

+1

All Articles