Ich möchte das Äquivalent der folgenden in LINQ zu tun, aber ich kann nicht herausfinden, wie:
IEnumerable<Item> items = GetItems();
items.ForEach(i => i.DoStuff());
Was ist die richtige Syntax?
Ich möchte das Äquivalent der folgenden in LINQ zu tun, aber ich kann nicht herausfinden, wie:
IEnumerable<Item> items = GetItems();
items.ForEach(i => i.DoStuff());
Was ist die richtige Syntax?
Ich möchte das Äquivalent der folgenden in LINQ zu tun, aber ich kann nicht herausfinden, wie:
Wie andere bereits festgestellt haben aquí und im Ausland LINQ und IEnumerable
Methoden sollen nebenwirkungsfrei sein.
Möchten Sie wirklich "etwas" mit jedem Element in der IEnumerable tun? Dann foreach
ist die beste Wahl. Die Leute sind nicht überrascht, wenn hier Nebenwirkungen auftreten.
foreach (var i in items) i.DoStuff();
Meiner Erfahrung nach sind Nebenwirkungen jedoch in der Regel nicht erforderlich. Meistens gibt es eine einfache LINQ-Abfrage, die nur darauf wartet, entdeckt zu werden, begleitet von einer StackOverflow.com-Antwort von Jon Skeet, Eric Lippert oder Marc Gravell, die erklärt, wie man das tun kann, was man will!
Wenn Sie tatsächlich nur einen Wert aggregieren (anhäufen), sollten Sie die Aggregate
Erweiterungsmethode.
items.Aggregate(initial, (acc, x) => ComputeAccumulatedValue(acc, x));
Vielleicht möchten Sie eine neue IEnumerable
aus den vorhandenen Werten.
items.Select(x => Transform(x));
Vielleicht möchten Sie auch eine Nachschlagetabelle erstellen:
items.ToLookup(x, x => GetTheKey(x))
Die Liste der Möglichkeiten (Wortspiel nicht ganz beabsichtigt) ist endlos.
Ich habe Fredriks Methode übernommen und den Rückgabetyp geändert.
Auf diese Weise unterstützt die Methode verzögerte Ausführung wie andere LINQ-Methoden.
EDIT : Falls dies nicht klar war: Jede Verwendung dieser Methode muss mit ToList() enden oder eine andere Möglichkeit, die Methode zu zwingen, auf die gesamte Aufzählungsliste zu wirken. Andernfalls würde die Aktion nicht ausgeführt werden!
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
foreach (T item in enumeration)
{
action(item);
yield return item;
}
}
Und hier ist der Test, um das zu sehen:
[Test]
public void TestDefferedExecutionOfIEnumerableForEach()
{
IEnumerable<char> enumerable = new[] {'a', 'b', 'c'};
var sb = new StringBuilder();
enumerable
.ForEach(c => sb.Append("1"))
.ForEach(c => sb.Append("2"))
.ToList();
Assert.That(sb.ToString(), Is.EqualTo("121212"));
}
Wenn Sie die ToList() am Ende wird der Test fehlschlagen, da der StringBuilder eine leere Zeichenfolge enthält. Das liegt daran, dass keine Methode ForEach zum Aufzählen gezwungen hat.
Ihre alternative Implementierung von ForEach
ist interessant, entspricht aber nicht dem Verhalten von List.ForEach
dessen Unterschrift lautet public void ForEach(Action<T> action)
. Es entspricht auch nicht dem Verhalten der Observable.ForEach
Erweiterung auf IObservable<T>
dessen Unterschrift lautet public static void ForEach<TSource>(this IObservable<TSource> source, Action<TSource> onNext)
. Übrigens, die ForEach
Äquivalent auf Scala-Sammlungen, auch diejenigen, die faul sind, haben auch Rückgabetyp, die void in C # entspricht.
Dies funktioniert genau so wie der Aufruf von Select
avec ToList
. Der Zweck der ForEach
ist es, nicht anrufen zu müssen ToList
. Sie sollte sofort ausgeführt werden.
Es gibt eine experimentelle Veröffentlichung von Microsoft von Interaktive Erweiterungen von LINQ (auch über NuGet siehe Das Profil von RxTeams für weitere Links). Die Kanal 9 Video erklärt es gut.
Die Dokumente werden nur im XML-Format bereitgestellt. Ich habe dies ausgeführt Dokumentation in der Sandburg um sie in ein lesbareres Format zu bringen. Entpacken Sie das Docs-Archiv und suchen Sie nach index.html .
Neben vielen anderen Vorteilen bietet es die erwartete ForEach-Implementierung. Sie ermöglicht es Ihnen, Code wie diesen zu schreiben:
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8 };
numbers.ForEach(x => Console.WriteLine(x*x));
Der funktionierende Link zu den interaktiven Erweiterungen: microsoft.com/download/de/details.aspx?id=27203
Solange ihre aktion thread-sicher ist, ist alles gut. aber was passiert, wenn sie eine nicht-thread-sichere aktion durchführen müssen? das kann ein ziemliches chaos verursachen...
Das stimmt. Es ist nicht thread-sicher, es werden verschiedene Threads aus einem Thread-Pool verwendet... Und ich muss meine Antwort revidieren. Wenn ich es jetzt versuche, gibt es kein ForEach(). Muss mein Code gewesen sein, der eine Erweiterung mit ForEach enthält, als ich darüber nachdachte.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
4 Stimmen
@pst: Ich habe diese Erweiterungsmethoden immer blindlings in meine Projekte gesteckt. Danke für diesen Artikel.
3 Stimmen
Es gibt MehrLINQ die eine
ForEach
Erweiterung .0 Stimmen
Hier ist eine alternative Idee, wie dies könnte möglich sein: visualstudio.uservoice.com/forums/121579-visual-studio-2015/
4 Stimmen
Das ist zwar nicht sehr sexy, aber es passt in eine Zeile, ohne eine Kopie über ToList - zu erstellen.
foreach (var i in items) i.Dostuff();
3 Stimmen
Einige dieser Links sind tot! Was war der Artikel, der so oft hochgevotet wurde?