Wenn Sie ein Wörterbuch anstelle eines Hashtable verwenden, so dass die Art der Schlüssel bekannt ist, ist der einfachste Weg, um eine Kopie der Schlüssel Sammlung zu machen, diese Ausnahme zu vermeiden ist:
foreach (string key in new List<string>(dictionary.Keys))
Warum erhalten Sie eine Ausnahme, die Ihnen mitteilt, dass Sie die Sammlung, über die Sie iterieren, geändert haben, obwohl Sie dies tatsächlich nicht getan haben?
Intern besitzt die Hashtable-Klasse ein Versionsfeld. Die Methoden Hinzufügen, Einfügen und Entfernen inkrementieren diese Version. Wenn Sie einen Enumerator für eine der Sammlungen erstellen, die die Hashtable verfügbar macht, enthält das Enumerator-Objekt die aktuelle Version der Hashtable. Die MoveNext-Methode des Enumerators prüft die Version des Enumerators anhand der Hashtable, und wenn sie nicht gleich sind, wird die angezeigte InvalidOperationException ausgelöst.
Dies ist ein sehr einfacher Mechanismus zur Bestimmung, ob die Hashtable geändert wurde oder nicht. In der Tat ist es ein bisschen zu einfach. Die Keys-Sammlung sollte eigentlich eine eigene Version beibehalten, und die GetEnumerator-Methode sollte die Version der Sammlung im Enumerator speichern, nicht die Version der Hashtable.
Bei diesem Ansatz gibt es einen weiteren, subtileren Konstruktionsfehler. Die Version ist ein Int32. Die UpdateVersion-Methode überprüft keine Grenzen. Es ist daher möglich, wenn Sie genau die richtige Anzahl von Änderungen an der Hashtable machen (2 mal Int32.MaxValue
, geben oder nehmen), damit die Version auf Hashtable und Enumerator gleich bleibt, obwohl Sie die Hashtable seit der Erstellung radikal geändert haben der Enumerator. Daher wird die MoveNext-Methode die Ausnahme nicht auslösen, obwohl dies erforderlich ist, und Sie erhalten unerwartete Ergebnisse.
glauben, dass dies eine Frage dup zu sehen ist: http://stackoverflow.com/questions/287195/how-to-add-items-to-a-collection -while-consuming-it –