为什么编译器会让这个漏掉?

时间:2011-11-10 14:59:29

标签: c#

  

可能重复:
  Foreach can throw an InvalidCastException?

考虑以下代码块

public class Base
{
}

public class DerivedLeft : Base
{
}

public class DerivedRight : Base
{
}

class Program
{
    static void Main(string[] args)
    {
        List<Base> list = new List<Base> { new DerivedLeft(), new DerivedRight() };
        foreach (DerivedLeft dl in list)
        {
            Console.WriteLine(dl.ToString());
        }
    }
}

注意foreach语句中从Base到DerivedLeft的强制转换。这编译得很好(Visual Studio 2010),没有任何错误甚至警告。 显然,在第二次循环迭代中,我们将得到一个InvalidCastException。 如果我被问到一个关于编译器对这些代码的反应的问题,我毫无疑问会说,编译器不会让这一点被忽视并产生至少一个警告。 但显然它没有。那么,为什么编译器会让这个漏掉呢?

3 个答案:

答案 0 :(得分:5)

它正在进行隐式演员表演。查看关于同一主题的这篇文章,以获得Jon Skeet的精彩解释:

Foreach can throw an InvalidCastException?

答案 1 :(得分:2)

因为列表的类型为List<Base>,而foreach循环中的变量dl的类型为DerivedLeft,其中Base为基类。所以它可以在运行时运行,但它不 。编译器没有检查列表的初始化。

答案 2 :(得分:0)

期望编译器在此处引发错误就像期望它在此引发错误:

Base b = new DerivedRight();
DerivedLeft d = (DerivedLeft)b;