今天我编写了一个使用两个嵌套的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,如果这有任何问题。
请告诉我发生了什么事。感谢。
答案 0 :(得分:8)
当迭代集合(使用foreach)时,不允许更改正在迭代的集合;但是当您选中匹配项的复选框时,外部循环(checkedListBoxItemList.Items
)的集合会发生变化,并且可能会吞下引发的后续错误。这或多或少解释了为什么你突然进入ToString
方法并且不继续循环。
当您使用for
语句进行迭代时,您没有这个限制,因为在您开始迭代时没有对该集合的引用。
希望这能解释。