entfernen würde, einen Schlüssel aus einem Wörterbuch in der foreach-ein problem? oder sollte ich besser zu konstruieren, die ein neues Wörterbuch?
Beispiel:
1.
foreach (var item in myDic)
{
if (item.value == 42)
myDic.remove(item.key);
}
würde der iterator funktioniert einwandfrei, egal wie die Aussagen in den inneren Klammern könnte möglicherweise beeinflussen myDic
?
2.
var newDic = myDic.where(x=>x.value!=42).ToDictionary(x=>x.key,x=>x.value);
Ist der 2. Ansatz eine gute Praxis? funktionale Programmierung und unveränderlich?
InformationsquelleAutor colinfang | 2011-08-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
Der erste Ansatz Absturz zur Laufzeit, da der enumerator stellt sicher, dass niemand löscht aus der zugrunde liegenden Erhebung, während es aufzählen.
Der zweite Ansatz ist ein netter Gedanke, aber C# dictionaries sind veränderlich und es ist weder idiomatisch, noch effizienter, um Sie zu kopieren, um, wenn Sie können das gleiche erreichen mit mutation.
Dies ist eine typische Art und Weise:
EDIT: In Antwort auf Ihre Frage in den Kommentaren. Hier ist, wie das Beispiel in Ihrem andere Frage funktioniert:
Diese Codezeile nicht ausgeführt werden kann alles; es ist Total faul. Sagen wir mal um des Arguments Willen, wir haben eine
foreach
nach, um es so Aussehen mehr wie in dieser Frage zum Vorbild nehmen.Wenn das ausgeführt wird, hier ist, was passieren wird, die bei jeder iteration:
MoveNext
auf der enumeratorCurrent
Eigenschaft, dassCurrent
Eigenschaft der Variablenn
Console.WriteLine
sKönnen Sie sehen, dass es kein Geheimnis und keine Endlosschleife und kein was auch immer.
Vergleichen Sie jetzt zu meinem Beispiel, angenommen, dass wir linken aus der
ToArray
.MoveNext
auf der enumeratorCurrent
Eigenschaft, dassCurrent
Eigenschaft der Variablenitem
Remove
sDies nicht funktioniert, weil, während es vollkommen in Ordnung zu
WriteLine
etwas aus einer Sammlung, während Sie haben ein enumerator auf Sie zu öffnen, Sie sind nicht erlaubt zuRemove
etwas aus einer Sammlung, während Sie haben ein enumerator auf Sie zu öffnen.Wenn Sie anrufen
ToArray
vorne, dann beginnen Sie durch die Aufzählung über das Wörterbuch und Auffüllen der array. Wenn wir uns auf dieforeach
, dieforeach
- Anweisung hat einen enumerator öffnen Sie auf der array, nicht das Wörterbuch. Sie sind berechtigt, zu entfernen aus dem Wörterbuch, wie Sie Durchlaufen das array.ToList()
ist schneller alsToArray()
.Der performance-Unterschied ist unbedeutend genug, dass ich in der Regel lieber nur je nachdem, was scheint mehr semantisch korrekte (das heißt, wenn ich nicht plan auf hinzufügen oder entfernen, halte ich mich mit
ToArray
.)Nein, kann man nicht weglassen. Wenn man es faul, dann wäre es immer noch aufzählen über das Wörterbuch, wenn
Remove
genannt wird, und Sie würden wieder da, wo Sie begonnen haben (mit einer Ausnahme zur Laufzeit.) Sie müssen alles tun, die Arbeit zu bauen, die Liste der Elemente zu entfernen, bevor Sie tatsächlich beginnen entfernen.Haben Sie verpasst .select(x=>x.Taste), um zur reform des Wörterbuch in der Liste?
Warum nicht einen one-liner?
myDic.Where(kvp => kvp.Value == 42).ToList.ForEach(kvp => myDic.Remove(kvp.Key));
InformationsquelleAutor mquander
Auch Sie können Durchlaufen die kopieren aus Ihrer Sammlung:
bemerken
myDic.ToList()
imforeach
- Anweisung.InformationsquelleAutor Vladislav