Question

  

Double possible:
   équivalent LINQ de foreach pour IEnumerable < T >

Les méthodes d’extension linq pour ienumerable sont très pratiques ... mais ce n’est pas très utile si vous voulez simplement appliquer un calcul à chaque élément de l’énumération sans rien retourner. Je me demandais donc si je manquais peut-être la bonne méthode ou si elle n'existait pas vraiment, car je préférerais utiliser une version intégrée si elle est disponible ... mais je n'en ai pas trouvé une: -)

J'aurais pu jurer qu'il y avait une méthode .ForEach quelque part, mais je ne l'ai pas encore trouvée. Entre-temps, j’ai écrit ma propre version au cas où elle serait utile à qui que ce soit:

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);
        }
    }
}

utilisation est:

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

Était-ce utile?

La solution

Nous éclairer un peu plus sur pourquoi:

LINQ est de nature fonctionnelle. Il est utilisé pour interroger des données et renvoyer des résultats. Une requête LINQ ne doit pas modifier l'état de l'application (à quelques exceptions près, comme la mise en cache). Parce que foreach ne donne aucun résultat, il n'a pas beaucoup d'utilisations qui n'impliquent pas de modifier l'état de quelque chose en plus de ce que vous lui transmettez. Et si vous avez besoin d’une méthode d’extension Foreach (), il est facile de lancer la vôtre.

Si, au contraire, vous souhaitez prendre une entrée et appeler une fonction sur chaque élément qui renvoie un résultat, LINQ vous permet d'accéder à sa méthode de sélection.

Par exemple, le code suivant appelle un délégué de fonction pour chaque élément d'une liste et renvoie true si cet élément est positif:

    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();        
    }

Autres conseils

En fait, la structure des extensions réactives de Microsoft Research a ajouté cette fonctionnalité. Dans l'assemblage System.Interactive, ils ont inclus une Run() et une Do() extension à IEnumerable<T>.

Do (action) exécute l'action sur chaque élément et la restitue. Ceci est utile pour ajouter la journalisation à une requête linq, par exemple:

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));

Cela se traduira par:

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

Exécuter (action) est comme une boucle foreach, ce qui signifie qu'il replie la séquence qui exécute l'action.

Vous pouvez en savoir plus à ce sujet ici: http://community.bartdesmet.net/blogs/bart/archive/2009/12/26/more-linq-with-system-interactive-the-ultimate-imperative. aspx

Le cadre Rx est disponible ici: http://msdn.microsoft. com / fr-us / devlabs / ee794896.aspx

La méthode ForEach sur List<T> effectue cette opération. Vous pouvez envelopper votre collection dans une liste, puis utiliser cet appel, mais ce n'est pas vraiment une bonne chose à faire. On dirait que vous devrez rouler vous-même.

Déjà discuté ici et , .

Je suis trop fatigué pour me souvenir, mais, fondamentalement, une méthode .ForEach dans une application à un seul thread est fonctionnellement équivalente à l'instruction foreach déjà existante. D'après ce que j'ai compris, la principale différence est qu'un ForEach pourrait être mis en parallèle, mais que cela introduirait trop facilement des comportements indésirables.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top