C# 在边界数组上循环时没有错误?

C# 在边界数组上循环时没有错误?,c#,winforms,C#,Winforms,我发现了一段应该会产生错误的代码,因为数组超出了界限,但它的行为却异常。当我进入时,它在4个循环后停止,不添加控件。这怎么可能,没有错误或编译器警告或任何东西 Panel[] panel = new Panel[4]; Label[] label = new Label[4]; private void Form1_Load(object sender, EventArgs e) { for (int x = 0; x < 20; x++)

我发现了一段应该会产生错误的代码,因为数组超出了界限,但它的行为却异常。当我进入时,它在4个循环后停止,不添加控件。这怎么可能,没有错误或编译器警告或任何东西

    Panel[] panel = new Panel[4];
    Label[] label = new Label[4];
    private void Form1_Load(object sender, EventArgs e)
    {
        for (int x = 0; x < 20; x++)
        {
            label[x] = new Label { Name = x.ToString("00"), BackColor = Color.Blue, Text = "Test" };
            panel[x] = new Panel { Name = x.ToString("00"), BackColor = Color.Blue };
        }
        tableLayoutPanel1.Controls.AddRange(label);
        tableLayoutPanel2.Controls.AddRange(panel);
    }
Panel[]Panel=新面板[4];
标签[]标签=新标签[4];
私有void Form1\u加载(对象发送方、事件参数e)
{
对于(int x=0;x<20;x++)
{
label[x]=新标签{Name=x.ToString(“00”),BackColor=Color.Blue,Text=“Test”};
panel[x]=新面板{Name=x.ToString(“00”),BackColor=Color.Blue};
}
tableLayoutPanel1.Controls.AddRange(标签);
tableLayoutPanel2.Controls.AddRange(面板);
}

如果将代码包装在try-catch中,您将看到抛出的异常。我的猜测是,当try-catch不存在时,异常会以某种方式被表单抛出和吞没

    void Form1_Load(object sender, EventArgs e)
    {
        try
        {
            for (int x = 0; x < 20; x++)
            {
                label[x] = new Label { Name = x.ToString("00"), BackColor = Color.Blue, Text = "Test" };
                panel[x] = new Panel { Name = x.ToString("00"), BackColor = Color.Blue };
            }
            this.Controls.AddRange(label);
            this.Controls.AddRange(panel);
        }
        catch (Exception ex)
        {
            this.Text = ex.Message;
        }

    }
void Form1\u加载(对象发送方,事件参数e)
{
尝试
{
对于(int x=0;x<20;x++)
{
label[x]=新标签{Name=x.ToString(“00”),BackColor=Color.Blue,Text=“Test”};
panel[x]=新面板{Name=x.ToString(“00”),BackColor=Color.Blue};
}
this.Controls.AddRange(标签);
此.Controls.AddRange(面板);
}
捕获(例外情况除外)
{
this.Text=例如消息;
}
}
此外,正如注释者所指出的,编译器不进行编译时数组边界检查

编辑:另请注意,这似乎仅在
窗体的
加载
事件处理程序中才需要。如果此代码位于除此之外的其他位置,则在正常调试时会中断(假定VisualStudio设置为在CLR异常时中断)

有关此问题的更多信息,请参见《伟大的汉斯·帕桑》(Hans Passant):


在这篇博文中,对答案进行了深入研究:

,这不会导致编译器错误。确实,您在运行时遇到了错误?编译器不执行边界检查,运行时执行。他是对的-我刚刚运行了这个,它在循环的第5次迭代中神奇地“停止”,并显示表单。看到这一点真的很奇怪,而且没有引发异常。编辑:需要包装它,或者将VS设置为在异常时中断。您可以签入
Debug->exceptions->Common Language Runtime exceptions->System.IndexOutOfRangeException
,它应该被选中。奇怪的是,我的VS设置为在所有CLR异常时中断,包括IOOR,但它并没有就此中断。我真的很好奇表单加载事件是如何神奇地吞下错误的。如何创建忽略事件的魔术错误!?另外,如果你在没有调试的情况下运行,我发现了一个新的线索。NET Framework说:
hello欢迎使用VBs的隐藏实现;按“继续”键可以神奇地跳过错误,谢谢您度过了愉快的一天。
因此,如果我正确理解这些链接,这是一个仅在64位机器上才会遇到的故障,嗯。。。将整个表单加载包装在一个try-catch中,该try-catch显示一个
MessageBox
,并关闭程序,这会模拟应该发生的情况吗?@codecamp是的,类似这样的操作是您需要做的,以确保用户不只是单击“继续”并使用未正确初始化的应用程序。