Как я уже упоминал в этом посте, я столкнулся с непонятным для меня поведением компилятора.
Код:
IEnumerable<IList<MyClass>> myData = //...getMyData
foreach (MyClass o in myData){}
Он компилируется, но не работает навремя выполнения: InvalidCastException;для меня это очевидно.
Если я изменю IList
на List
следующим образом, он пожалуется:
IEnumerable<List<MyClass>> myData = //...getMyData
foreach (MyClass o in myData){}
Когда вместо типа класса я ставлю var
какдалее intellisense распознает правильный тип:
IEnumerable<List<MyClass>> myData = //...getMyData
foreach (var o in myData){}
Мой первый вопрос был: Почему компилятор не жалуется?Ответ состоял в том, что поведение соответствует определению C # Language .См. Главу 6.2.4 Явные преобразования ссылок, стр. 116.
Прочитайте 4-е и 5-е утверждение:
• От любого типа интерфейса S к любому типу класса T, если T не запечатан или если T реализует S.
• От любого типа интерфейса S к любому интерфейсу-типа T, при условии, что S не является производным от T.
Для второй части первого утверждения provided T implements S
ясно, без сомнения.Но почему мы можем привести тип интерфейса S к любому типу класса T, если он не выведен или не реализован?В каком случае / сценарии с непустым списком будет работать код без выброса InvalidCastException
?