2013-06-21 180 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

他是對的 - 我只是跑了這個,並且在第五次循環中神奇地「停止」了,並顯示了表格。真的很奇怪看到這一點,並沒有拋出異常。編輯:需要包裝它,或設置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; 
     } 

    } 

此外,正如評論者所指出的,編譯器不會進行編譯時數組邊界檢查。

編輯:額外的注意,這似乎只需要在FormLoad事件處理程序中。如果此代碼在其他位置,則在正常調試時會中斷(假定您的Visual Studio設置爲在CLR異常中斷)。

更多從大漢斯帕桑特這個問題: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位機器上經歷,如果我正確理解這些鏈接嗯......將包裝整個表單加載在try catch顯示一個'MessageBox'並關閉程序幾乎模擬應該發生什麼? – CodeCamper

+0

@CodeCamper是的,類似的東西是你需要做的,以確保用戶不只是點擊「繼續」,並使用不正確的初始化應用程序。 – Gjeltema