Ändern der Sammlung bei Verwendung einer foreach-Schleife in c # [duplizieren]

8

Grundsätzlich möchte ich einen Gegenstand aus einer Liste entfernen, während er in der foreach-Schleife ist. Ich weiß, dass dies möglich ist, wenn ich eine for-Schleife verwende, aber für andere Zwecke würde ich gerne wissen, ob dies mit einer foreach-Schleife erreichbar ist.

In Python können wir das folgendermaßen erreichen:

%Vor%

Dies ergibt die folgende Ausgabe

%Vor%

Aber wenn ich etwas Ähnliches in c # mache, bekomme ich eine InvalidOperationException, ich frage mich, ob es eine Möglichkeit gibt, dies zu umgehen, ohne einfach eine for-Schleife zu benutzen .

Der Code in c #, den ich benutzt habe, als die Ausnahme ausgelöst wurde:

%Vor%

Vielen Dank im Voraus

    
ThePower 14.07.2009, 08:49
quelle

3 Antworten

25

Sie können das nicht tun. Aus den Dokumenten für IEnumerator<T> :

  

Ein Enumerator bleibt solange gültig wie   Die Sammlung bleibt unverändert. Ob   Änderungen werden an der Sammlung vorgenommen,   wie Hinzufügen, Ändern oder Löschen   Elemente, der Enumerator ist   unwiderruflich für ungültig erklärt und sein   Verhalten ist undefiniert.

Alternativen sind:

  • Erstellen Sie eine neue Liste mit Elementen, die entfernt werden sollen, und entfernen Sie sie anschließend alle
  • Benutze eine normale "for" -Schleife und achte darauf, dass du nicht zweimal über dasselbe Element gehst oder etwas verpasst. (Du hast gesagt, dass du das nicht tun willst, aber was du versuchst zu tun, wird einfach nicht funktionieren.)
  • Erstellen Sie eine neue Sammlung, die nur die Elemente enthält, die Sie behalten möchten

Die letzte dieser Alternativen ist die LINQ-ähnliche Lösung, in der Sie normalerweise schreiben würden:

%Vor%

(Wo ShouldBeRetained natürlich die von Ihnen gewünschte Logik ist.) Der Aufruf von ToList() ist nur dann notwendig, wenn Sie ihn wirklich in einer Liste haben wollen. Dies führt zu mehr deklarativem Code, der oft leichter zu lesen ist. Ich kann nicht leicht erraten, was deine ursprüngliche Schleife machen soll (es scheint im Moment ziemlich seltsam zu sein), wohingegen wenn du die Logik rein in Bezug auf den Gegenstand ausdrücken kannst, kann es viel klarer sein.

    
Jon Skeet 14.07.2009, 08:53
quelle
6

Wenn Sie nur alle Elemente entfernen müssen, die eine Bedingung erfüllen, können Sie die Liste & lt; T & gt; .RemoveAll Methode:

%Vor%

Beachten Sie, dass dies die ursprüngliche Liste ändert.

    
Darin Dimitrov 14.07.2009 09:10
quelle
1

Sie dürfen auf keinen Fall eine Sammlung ändern, wenn Sie eine foreach-Schleife darauf verwenden.

Sie können eine for-Schleife verwenden und den Index für sich selbst verwalten oder eine Kopie der Sammlung erstellen und beim Loopen des Originals Elemente aus der Kopie entfernen, die dem Objekt im Original entsprechen.

In beiden Fällen ist es nicht ganz so klar oder praktisch:).

    
Robert 14.07.2009 08:54
quelle