正如我在书中提到的
this
发帖后,我面对一个对我来说不可理解的编译器行为。
代码:
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 definition
.见第116页第6.2.4章明确参考转换。
阅读第4条和第5条声明:
从任何接口类型S到任何类类型T,前提是T未密封或T实现S。
从任何接口类型S到任何接口类型T,前提是S不是从T派生的。
对于第一个声明的第二部分
provided T implements S
这很清楚,毫无疑问。
但我们为什么要将接口类型强制转换为S
任何
类类型T,如果是
不
派生或
不
实施?
在这种情况下,如果列表为非空,代码运行时不会抛出
InvalidCastException
?