2013-06-21 3 views
1

Я обнаружил фрагмент кода, который должен вызывать ошибку, потому что массив выходит за границы, но вместо этого он ведет себя странно. Когда я вхожу в него, он просто останавливается после 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); 
    } 
+0

Это не приведет к ошибке компиляции. Неужели вы на самом деле получаете ошибку во время выполнения? –

+1

Компилятор не выполняет проверку границ, выполняется время выполнения. – spender

+0

Он прав - я просто побежал, и он просто волшебным образом «останавливается» на 5-й итерации по петле и отображает форму. Действительно странно видеть, что и никакое исключение не было брошено. Изменить: нужно обернуть его или установить VS для исключения исключений. – Gjeltema

ответ

3

Если вы завернете код в 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; 
     } 

    } 

Также, как отмечают комментаторы, компилятор не выполняет проверку границ массива во время компиляции.

Редактировать: примечание, это только кажется необходимым, если в обработчике событий Load для Form. Если этот код находится в другом месте, он ломается при обычной отладке (предполагая, что Visual Studio настроен на прерывание исключений CLR).

Подробнее об этой проблеме от великого Ганса Passant: Why the form load can't catch exception?

И сверление ответов заканчивается на этом блоге: http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/

+0

Мне действительно интересно, как событие загрузки формы волшебным образом проглатывает ошибку. Как создать магическую ошибку, игнорируя события !? Также я нашел новую подсказку, если вы запускаете без отладки. .NET Framework говорит: «привет приветствую скрытую реализацию VB на ошибке goto break; пресса продолжает волшебно пропускать ошибки, спасибо, что у вас хороший день. « – CodeCamper

+0

Так что это сбой, который испытывается только на 64-битных машинах, если я правильно понимаю эти ссылки, хммм ... будет обертывать всю нагрузку на форму в попытке поймать, что отображает «MessageBox» и закрывает программу, почти подражая тому, что должно произойти? – CodeCamper

+0

@CodeCamper Да, что-то вроде того, что вам нужно сделать, чтобы пользователи не просто нажимали «Продолжить» и использовали неправильно инициализированное приложение. – Gjeltema