为什么这个隐式转换不会导致编译时错误?

时间:2016-01-18 14:18:30

标签: c# .net implicit-cast

只是想了解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
{
}

虽然第一次迭代成功,但第二次迭代没有成功。老实说,我预计这会在编译时失败。有谁知道它为什么只在运行时失败?

1 个答案:

答案 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)的集合,现在,为了向后兼容,它无法更改。