2010-04-28 7 views
5

Heute habe ich eine Funktion codiert, die zwei verschachtelte foreach-Schleifen verwendet. Nachdem ich gesehen habe, dass es nicht wie erwartet funktioniert hat, habe ich es ausgepackt. Aber ich sehe keinen Fehler, und denke nicht, dass ein einfacher Fehler das Verhalten verursachen kann, das ich bemerkt habe.C# - foreach zeigt seltsames Verhalten/zum Arbeiten ohne Probleme

Das Teil sieht wie folgt aus:

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

Lassen Sie uns sagen, checkedListBoxItemList.items hält 4 Elemente des Typs MyClass und ActiveItemList ist eine Liste < MyClass> mit 2 Artikel.

Der Debugger springt in die äußere foreach, erreicht innere foreach, führt die if 2 mal (einmal pro cActiveItem) und erreicht das Ende der äußeren foreach.Now, springt der Debugger zurück zum Kopf der äußeren foreach als es sollte. Aber statt die zweite Runde der äußeren foreach zu starten, springt der Debugger plötzlich in die MyClass.ToString() -Methode. Ich kann diese Methode 4 mal durchlaufen (Anzahl der Elemente in checkedListBoxItemList.Items) und dann ... nichts. Visual Studio zeigt mir meine Windows-Form, und die Foreach wird nicht fortgesetzt.

Bei einer Änderung des Codes zu

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

alles funktioniert und wie soll. Ich habe das Problem einem Kollegen gezeigt, aber er hat auch nicht verstanden, was passiert ist. Ich verstehe nicht, warum der Debugger in die MyClass.ToString() -Methode springt. Ich habe F10 benutzt, um durchzukommen, also muss ich die Funktion nicht verlassen. Und selbst wenn es einen Grund gibt, warum wird die foreach-Schleife nicht fortgesetzt?

Ich benutze Visual Studio 2010, wenn dies von Bedeutung ist.

Bitte sagen Sie mir, was passiert ist. Vielen Dank.

+1

Was ist der Typ von 'checkedListBoxItemList'? Ich glaube, es muss "IEnumerable" implementieren, um mit "foreach" verwendet zu werden, und ich sehe nicht, wo Sie erwähnt haben, welcher Typ es war. –

+0

Offensichtlich hat checkedListBoxItemList den Typ checkedListBox. Aber nicht über die ListBox, sondern über checkedListBoxItemList.Items. Dies ist vom Typ CheckedItemCollection und implementiert IEnumerable. – Marks

Antwort

7

Beim Iterieren einer Sammlung (mithilfe einer Foreach) darf die zu wiederholende Sammlung nicht geändert werden. Wenn Sie jedoch das Kontrollkästchen für das übereinstimmende Element aktivieren, ändert sich die Auflistung der äußeren Schleife (checkedListBoxItemList.Items), und der folgende Fehler wird wahrscheinlich irgendwo verschluckt. Das erklärt mehr oder weniger, warum Sie plötzlich in die ToString Methode gehen und die Schleife nicht fortsetzen.

Wenn Sie eine for-Anweisung zum Iterieren verwenden, haben Sie diese Einschränkung nicht, da zum Zeitpunkt der Iteration kein Verweis auf die Sammlung vorhanden ist.

Hoffe das erklärt.

+0

Danke. Ich wusste, dass ich die iterierende Sammlung nicht ändern kann. Aber da .Items eine Sammlung meiner MyClass-Objekte ist und den überprüften Zustand nicht enthält, dachte ich, es wäre in Ordnung. Sollte der Compiler dieses Problem nicht bemerken? Ich erinnere mich an Compilerfehler, die mir sagten, dass ich Iterationsobjekte in der Vergangenheit nicht ändern sollte. Irgendwelche Hinweise darauf, warum der Debugger mich in die ToString-Methode führt? Ich sehe keinen Grund dafür, seit ich F10 benutzt habe (Step over). – Marks