Frage

  

Mögliche Duplizieren:
   LINQ Äquivalent foreach für IEnumerable

Die Linq-Erweiterungsmethoden für IEnumerable sind sehr praktisch ... aber nicht so nützlich, wenn alles, was Sie tun möchten, ist eine Berechnung zu jedem Element in der Aufzählung anwenden, ohne etwas zurück. Also habe ich mich gefragt, ob vielleicht war ich nur die richtige Methode fehlt, oder ob es wirklich existiert nicht, da ich eher eine integrierte Version verwenden würde, wenn es verfügbar ist ... aber ich habe nicht eine gefunden: -)

ich hätte schwören können eine .ForEach Methode irgendwo war, aber ich habe es noch zu finden. In der Zwischenzeit habe ich meine eigene Version für den Fall schreiben Sie es für jedermann nützlich ist anders:

using System.Collections;
using System.Collections.Generic;

public delegate void Function<T>(T item);
public delegate void Function(object item);

public static class EnumerableExtensions
{
    public static void For(this IEnumerable enumerable, Function func)
    {
        foreach (object item in enumerable)
        {
            func(item);
        }
    }

    public static void For<T>(this IEnumerable<T> enumerable, Function<T> func)
    {
        foreach (T item in enumerable)
        {
            func(item);
        }
    }
}

Nutzung ist:

myEnumerable.For<MyClass>(delegate(MyClass item) { item.Count++; });

War es hilfreich?

Lösung

Shedding ein wenig mehr Licht auf, warum:

LINQ ist funktional in der Natur. Es wird verwendet, um Daten abzufragen und Ergebnisse zurück. Eine LINQ-Abfrage sollte nicht den Status der Anwendung werden zu verändern (mit einigen Ausnahmen wie Caching). Da foreach keine Ergebnisse zurück, hat es nicht viele Anwendungen, die nicht mit dem Zustand etwas zu ändern außer dem, was Sie vorbei in ihn. Und wenn Sie eine foreach () Erweiterungsmethode benötigen, ist es ist einfach Ihre eigene Rolle.

Wenn auf der anderen Seite, was wollen Sie eingegeben nehmen und eine Funktion für jedes Element aufrufen, die ein Ergebnis zurückgibt, LINQ bietet eine Möglichkeit, durch die select-Methode.

Zum Beispiel der folgende Code ruft eine Funktion Delegierten auf jedem Element in einer Liste und gibt true zurück, wenn das Element positiv ist:

    static void Main(string[] args)
    {
        IEnumerable<int> list = new List<int>() { -5, 3, -2, 1, 2, -7 };
        IEnumerable<bool> isPositiveList = list.Select<int, bool>(i => i > 0);

        foreach (bool isPositive in isPositiveList)
        {
            Console.WriteLine(isPositive);
        }

        Console.ReadKey();        
    }

Andere Tipps

Eigentlich hat der Reactive Extensions Framework von Microsoft Research diese Funktionalität hinzuzufügen. In der System.Interactive Versammlung haben sie eine Run() und eine Do() Erweiterung enthalten IEnumerable<T>.

Do (Aktion) wird die Aktion für jedes Element ausführen und wieder ergeben. Dies ist nützlich für zu einer Linq-Abfrage zum Beispiel das Hinzufügen Protokollierung:

var res = GetRandomNumbers(100).Take(10)
      .Do(x => Console.WriteLine("Source  -> {0}", x))
      .Where(x => x % 2 == 0)
      .Do(x => Console.WriteLine("Where   -> {0}", x))
      .OrderBy(x => x)
      .Do(x => Console.WriteLine("OrderBy -> {0}", x))
      .Select(x => x + 1)
      .Do(x => Console.WriteLine("Select  -> {0}", x));

Dies führt zu:

Source  -> 96 
Where   -> 96 
Source  -> 25 
Source  -> 8 
Where   -> 8 
Source  -> 79 
Source  -> 25 
Source  -> 3 
Source  -> 36 
Where   -> 36 
Source  -> 51 
Source  -> 53 
Source  -> 81 
OrderBy -> 8 
Select  -> 9 
9 
OrderBy -> 36 
Select  -> 37 
37 
OrderBy -> 96 
Select  -> 97 
97

Run (action) ist wie ein foreach Schleife, was bedeutet, deren Sequenz der Falten, die die Aktion ausgeführt wird.

Sie können mehr darüber lesen Sie hier: http://community.bartdesmet.net/blogs/bart/archive/2009/12/26/more-linq-with-system-interactive-the-ultimate-imperative. aspx

Der Rx Rahmen finden Sie hier: http://msdn.microsoft. com / en-us / DevLabs / ee794896.aspx

Die ForEach-Methode auf List<T> tut dies. Sie könnten Ihre Sammlung in einer Liste wickeln und dann diesen Anruf verwenden, aber das ist nicht wirklich eine schöne Sache zu tun. Sieht aus wie Sie Ihre eigene Rolle werden müssen.

Bereits diskutiert und dort .

Im zu schläfrig zu erinnern, aber im Grunde genommen ein .ForEach Verfahren in einer einzigen Thread Anwendung funktional äquivalent ist die bereits bestehende foreach-Anweisung. Von dem, was ich verstehe, ist der wesentliche Unterschied, dass ein FürJeden parallized werden könnte, aber das wäre zu leicht unerwünschtem Verhalten einzuführen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top