6

今天我编写了一个使用两个嵌套 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 是一个具有 2 个项目的 List< MyClass >。

调试器跳入外部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,如果有任何问题的话。

请告诉我发生了什么事。谢谢。

4

1 回答 1

9

当迭代一个集合时(使用一个foreach),你正在迭代的集合是不允许改变的;但是当您选中匹配项的复选框时,外部循环 ( checkedListBoxItemList.Items) 的集合会发生变化,并且引发的随之而来的错误可能会在某处被吞没。这或多或少解释了为什么您突然进入该ToString方法并且不继续循环。

当您使用for语句进行迭代时,您没有该限制,因为在您开始迭代时没有对集合的引用。

希望这能解释。

于 2010-04-28T14:48:12.383 回答