2010-04-28 53 views
5

今天我編寫了一個函數,使用兩個嵌套的foreach循環。看到後,它沒有像預期的那樣工作,我調試了它。但是我沒有看到錯誤,並且不認爲一個簡單的錯誤會導致我注意到的行爲。C# - foreach顯示奇怪的行爲/沒有問題

的部分看起來像這樣:

foreach(MyClass cItem in checkedListBoxItemList.Items) 
{ 
    foreach(MyClass cActiveItem in ActiveItemList) 
    { 
     if (cActiveItem.ID == cItem.ID) /*...check checkbox for item...*/; 
    } 
} 

比方說,checkedListBoxItemList.items擁有4項MyClass類型的,並且ActiveItemList是一個List < MyClass的> 2項。

調試器跳轉到外部foreach,到達內部foreach,執行if 2次(每個cActiveItem一次)併到達外部foreach的末尾。現在,調試器跳回到外部foreach的頭部,因爲它應該。但不是開始第二輪外部foreach,調試器突然跳入MyClass.ToString()方法。 我可以通過這個方法4次(checkedListBoxItemList.Items中的項目數) ,然後......沒什麼。 Visual Studio向我展示了我的Windows窗體,並且該foreach不再繼續。

當改變代碼

int ListCount = checkedListBoxItemList.Items.Count; 
for(int i=0; i<ListCount; i++) 
{ 
    MyClass cItem = checkedListBoxItemList.Items[i] as MyClass; 
    foreach(MyClass cActiveItem in ActiveItemList) 
    { 
     if (cActiveItem.ID == cItem.ID) /*...check checkbox for item...*/; 
    } 
} 

一切工作正常,像預想的那樣。 我向同事展示了這個問題,但他也不明白,發生了什麼事。我不明白爲什麼調試器跳轉到MyClass.ToString()方法。我用F10來完成,所以不需要離開這個功能。甚至,如果有什麼原因,爲什麼不繼續foreach循環?

即時通訊使用Visual Studio 2010,如果這是任何事情。

請告訴我發生了什麼事。謝謝。

+1

'checkedListBoxItemList'的類型是什麼?我相信它必須實現'IEnumerable'才能與'foreach'一起使用,並且我沒有看到你提到的是哪種類型。 – 2010-04-28 14:44:39

+0

顯然checkedListBoxItemList的類型是checkedListBox。但即時通訊不是迭代ListBox,而是遍歷checkedListBoxItemList.Items。 這是類型CheckedItemCollection並實現IEnumerable。 – Marks 2010-04-29 07:23:50

回答

7

迭代集合(使用foreach)時,您正在迭代的集合不允許更改;但是當您檢查匹配項目的複選框時,外部循環(checkedListBoxItemList.Items)的集合發生更改,並且引發的隨後的錯誤可能會在某處被吞噬。這或多或少地解釋了爲什麼你突然進入ToString方法並且不繼續循環。

當您使用for語句進行迭代時,您沒有該限制,因爲在開始迭代時沒有對集合的引用。

希望這解釋。

+0

謝謝。我知道我不能改變迭代集合。但是因爲.Items是MyClass對象的集合,並且不支持checked狀態,所以我認爲它會好的。編譯器是否應該注意到這個問題?我記得編譯器錯誤,告訴我不要在過去改變迭代對象。 關於爲什麼調試器將我帶入ToString方法的任何線索?我沒有看到它的原因,因爲我使用F10(逐步)。 – Marks 2010-04-29 06:52:44