Пояснение к языку C # Спецификация: 6.2.4 Явные преобразования ссылок - PullRequest
0 голосов
/ 03 декабря 2018

Как я уже упоминал в этом посте, я столкнулся с непонятным для меня поведением компилятора.

Код:

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?

...