diese Frage Nach Foreach loop for disposing controls skipping iterations es nervte mich, dass Iteration über eine sich verändernde Sammlung erlaubt wurde:Warum wirft ControlCollection keine InvalidOperationException?
Zum Beispiel die folgenden:
List<Control> items = new List<Control>
{
new TextBox {Text = "A", Top = 10},
new TextBox {Text = "B", Top = 20},
new TextBox {Text = "C", Top = 30},
new TextBox {Text = "D", Top = 40},
};
foreach (var item in items)
{
items.Remove(item);
}
wirft
InvalidOperationException: Die Auflistung wurde geändert; Aufzählungsoperation wird möglicherweise nicht ausgeführt.
jedoch in einer .NET-Formular können Sie tun:
this.Controls.Add(new TextBox {Text = "A", Top = 10});
this.Controls.Add(new TextBox {Text = "B", Top = 30});
this.Controls.Add(new TextBox {Text = "C", Top = 50});
this.Controls.Add(new TextBox {Text = "D", Top = 70});
foreach (Control control in this.Controls)
{
control.Dispose();
}
, welche Elemente überspringt, weil das der Iterator über eine sich verändernde Sammlung läuft, ohne eine Ausnahme zu werfen
Bug? sind nicht Iteratoren erforderlich, um InvalidOperationException
zu werfen, wenn sich die darunterliegende Sammlung ändert?
Also meine Frage ist Warum löst Iteration über eine Änderung ControlCollection
NICHT InvalidOperationException?
Nachtrag:
Die Dokumentation für IEnumerator
sagt:
Der enumerator keinen exklusiven Zugriff hat auf die Sammlung; Daher ist das Aufzählen durch eine Sammlung an sich kein Thread-sicheres Verfahren. Selbst wenn eine Auflistung synchronisiert wird, können andere Threads die Auflistung weiterhin ändern, die verursacht, den Enumerator eine Ausnahme zu werfen.
https://msdn.microsoft.com/en-us/library/system.collections.ienumerator%28v=vs.100%29.aspx
ändert sich 'this.Controls.Count' nachdem die' foreach' abgeschlossen ist? Ich denke, die controllCollection selbst ändert sich nicht. –
@AmitKumarGhosh Ja, da die ControlsCollection den Index der verbleibenden Steuerelemente nach jedem Aufruf von 'Control.ControlCollection.Remove()' neu anordnet – Marco
Nicht alle Auflistungen implementieren dieses Feature. –