2010-02-27 14 views
12

Ich bin mit einem Wörterbuch und ich möchte es ändern, während ich durch sie aufzählen, aber es scheint, das ist nicht erlaubt. Wie kann ich das tun?Ändern von .NET-Wörterbuch beim Aufzählen durch

Dank

+0

Haben Sie den Schlüssel oder den Wert ändern möchten? –

+1

Du würdest keine Brücke neu bauen wollen, während du dabei bist, ja? Vielleicht möchten Sie das auf andere Weise implementieren. –

+5

@ [o.k.w] Ob Sie es glauben oder nicht, aber so werden riesige Brücken gebaut und modifiziert/repariert. Und wenn ich ein riesiges Wörterbuch habe und jeden Wert ändern muss, würde ich die Schlüssel lieber nicht zuerst klonen. –

Antwort

5

Sie sollten den Schlüssel oder das Objekt, das Sie löschen möchten, speichern und die Schleife unterbrechen. Anschließend können Sie das Objekt mithilfe der remove-Methode aus dem Wörterbuch löschen.

this helps

1

antwortete ich es here bezüglich der Schlange stehen, aber die Antwort ist die gleiche. Sie können nicht mit foreach aufzählen und die Sammlung gleichzeitig ändern.

10

tun, nicht grundsätzlich. Es wird explizit nicht unterstützt. Aus der Dokumentation für Dictionary<,>.GetEnumerator():

Ein Enumerator bleibt gültig, solange die Sammlung unverändert bleibt. Wenn Änderungen an der Sammlung vorgenommen werden, wie Hinzufügen, Ändern oder Löschen von Elementen, ist der Enumerator unwiderruflich ungültig und seine Verhalten ist undefiniert.

Normalerweise ist es am besten, wenn Sie sich die Änderungen, die Sie vornehmen möchten, merken und diese anschließend ausführen können. Oder Sie können eine Kopie des Wörterbuchs erstellen, um damit zu beginnen und dann das durchlaufen, während Sie das Original ändern. Wenn Sie uns mehr Informationen darüber geben könnten, was Sie vorhaben, würde das helfen.

Nach diesen Worten, die neue ConcurrentDictionary Klasse in .NET 4.0 tut dies zulassen - aber die Ergebnisse der Iteration nicht garantiert werden - die Änderungen sehen können, während Sie laufen, oder können Sie nicht.

+1

Vielleicht genauer ist, dass sie keine gute Möglichkeit finden konnten, IllegalOperationException für ConcurrentDictionary zu werfen. Es wird eine Menge Ärger verursachen. Ich würde es sicherlich nicht empfehlen. –

+1

@nobugz: Ich bezweifle sehr, dass es daran liegt, dass sie * IllegalOperationException nicht auslösen konnten. Der Punkt der gleichzeitigen Sammlungen ist, dass Sie * Dinge * gleichzeitig mit ihnen tun können - das beinhaltet das Iterieren.Jetzt möchten Sie normalerweise die Sammlung in demselben Thread ändern, der iteriert (was leicht zu vermeiden ist), aber im allgemeinen Fall ist es viel schwieriger. –

+0

das Warum ist nicht wirklich relevant, die Tatsache, dass es die Ausnahme nicht wirft, ist. Es gibt eine Menge Programmierer hier, die Ihre Beiträge als Evangelium nehmen, ich muss Sie auffordern, die Auswirkungen Ihres Rates zu berücksichtigen. Wenn das Wörterbuch während der Iteration mutiert wird, egal ob vom selben Thread oder von einem anderen, hat Heisenbug es überall geschrieben. Aus dem Blick auf den reflektierten Quellcode macht ConcurrentDirectronic nichts, um Missgeschicke zu vermeiden. Und die MSDN-Dokumente sind völlig still darüber. –

1

Ich geriet in eine ähnliche Situation bei der Arbeit. Ich musste ein Wörterbuch ändern, während ich es iterativ kleiner machte, bis ich keine Schlüssel/Werte mehr hatte.

Ich begann mit dem Erstellen einer Liste von "entfernt" -Tasten, aber es war schmerzhaft langsam mit all den anderen Logik, die ich implementieren musste. Alternativ habe ich das Wörterbuch rückwärts durchlaufen. Da Sie das Wörterbuch von hinten nach vorne durchlaufen, verursacht die Iteration keinen Fehler.

Nachdem ich meine Arbeit im Zusammenhang Logik herausnehmen, sieht es albern, aber ich verspreche, es funktioniert und sieht ungefähr so ​​aus:

Dictionary<int, List<int>> dict = new Dictionary<int, List<int>>(); 
    while(dict.Any()) 
    { 
     foreach(var key in dict.Keys.Reverse()) 
     { 
      if(//conditional) 
      { 
       dict.Remove(key); 
      } 
      else 
      { 
       //do something with dict[key] 
      } 
     } 
    } 
Verwandte Themen