views:

82

answers:

1

Hi there. Today I coded a function that uses two nested foreach loops. After seeing, that it did not work like expected, i debugged it. But I dont see an error, and dont think a simple error can cause the behavior i have noticed.

The part looks like this:

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

Lets say, checkedListBoxItemList.items holds 4 items of type MyClass, and ActiveItemList is a List< MyClass > with 2 Items.

The debugger jumps into the outer foreach, reaches inner foreach, executes the if 2 times (once per cActiveItem) and reaches the end of the outer foreach.Now, the debugger jumps back to the head of the outer foreach as it should. But instead of starting the second round of the outer foreach, the debugger suddenly jumps into the MyClass.ToString() method. I can step through this method 4 times (number of items in checkedListBoxItemList.Items) and then ... nothing. Visual Studio shows me my windows form, and the foreach is not continued.

When changing the code to

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...*/;
   }
}

everything works fine and as supposed. I showed the problem to a collegue, but he also didnt understand, what happened. I dont understand why the debugger jumps into the MyClass.ToString() method. I used F10 to step through, so no need to leave the function. And even, if there is a reason, why isnt the foreach loop continued?

Im using Visual Studio 2010, if this is of any matter.

Please tell me what happened. Thanks.

+7  A: 

When iterating a collection (using a foreach), the collection you are iterating is not allowed to change; but when you check the checkbox for the matching item, the collection of the outer loop (checkedListBoxItemList.Items) changes and the consequent error that is thrown is probably swallowed somewhere. That more or less explains why you suddenly go into the ToString method and don't continue the loop.

When you use a forstatement to iterate, you don't have that restriction as there is no reference to the collection at the moment you start iterating.

Hope this explains.

Thomas
Thanks. I knew that I can not change the iterating collection. But since .Items is a collection of my MyClass objects, and doesnt hold the checked state, I thought it would be ok. Should't the compiler notice that problem? I remember compiler errors telling me not to change iteration objects in the past.Any clue on why the debugger is leading me into the ToString method? I dont see a reason for it since i used F10 (Step over).
Marks