正如我在这篇文章中提到的,我面临着一种对我来说无法理解的编译器行为。
编码:
IEnumerable<IList<MyClass>> myData = //...getMyData
foreach (MyClass o in myData){}
它编译,但在运行时失败:InvalidCastException;对我来说,这很明显。
如果我将其更改IList
为List
如下,它会抱怨:
IEnumerable<List<MyClass>> myData = //...getMyData
foreach (MyClass o in myData){}
当而不是我如下放置的类类型时var
,智能感知识别正确的类型:
IEnumerable<List<MyClass>> myData = //...getMyData
foreach (var o in myData){}
我的第一个问题是:为什么编译器不抱怨?答案是该行为尊重C# 语言定义。参见章节 6.2.4 显式引用转换,第 116 页。
阅读第 4 条和第 5 条语句:
• 从任何接口类型 S 到任何类类型 T,只要 T 不是密封的或提供 T 实现 S。
• 从任何接口类型 S 到任何接口类型 T,前提是 S 不是从 T 派生的。
对于第一个陈述的第二部分provided T implements S
是明确的,毫无疑问。但是,如果接口类型 S不是派生的或未实现的
,为什么我们要将它强制转换为任何类类型 T呢?
在哪种情况下/场景中具有非空列表的代码将在不抛出? 的情况下运行?InvalidCastException