只是想了解C#。仅考虑以下简化示例。
void Main()
{
IList<IAnimal> animals = new List<IAnimal>
{
new Chicken(),
new Cow(),
};
// Shouldn't this line result in a compile-time error?
foreach (Chicken element in animals)
{
}
}
public interface IAnimal
{
}
public class Cow : IAnimal
{
}
public class Chicken : IAnimal
{
}
虽然第一次迭代成功,但第二次迭代没有成功。老实说,我预计这会在编译时失败。有谁知道它为什么只在运行时失败?
答案 0 :(得分:5)
因为foreach
语句在C# Language Specification中定义为具有(隐藏)显式强制转换:
以上步骤,如果成功,则明确地生成集合类型C,枚举器类型E和元素类型T.表单的foreach语句
foreach (V v in x) embedded-statement
然后扩展为:
{
E e = ((C)(x)).GetEnumerator();
try {
while (e.MoveNext()) {
V v = (V)(T)e.Current;
embedded-statement
}
}
finally {
… // Dispose e
}
}
(注意(V)(T)e.Current
,“显式”强制转换为V
)
不幸的是,它是这样定义的,因为这是你在C#1中真正需要的(在泛型之前,你要在foreach
中迭代的每个集合都是object
)的集合,现在,为了向后兼容,它无法更改。