web-dev-qa-db-fra.com

Linq style "pour chaque"

Duplicate possible:
équivalent Linq de foreach pour IEnumerable

Existe-t-il une syntaxe de style Linq pour les opérations "Pour chaque"?

Par exemple, ajoutez des valeurs basées sur une collection à une autre déjà existante:

IEnumerable<int> someValues = new List<int>() { 1, 2, 3 };

IList<int> list = new List<int>();

someValues.ForEach(x => list.Add(x + 1));

Au lieu de

foreach(int value in someValues)
{
  list.Add(value + 1);
}
173

L'utilisation de la méthode d'extension ToList () est votre meilleure option:

someValues.ToList().ForEach(x => list.Add(x + 1));

Il n'y a pas de méthode d'extension dans la BCL qui implémente directement ForEach.


Bien qu'il n'y ait pas de méthode d'extension dans le BCL qui fait cela, il y a reste une option dans l'espace de nom System ... si vous ajoutez Reactive Extensions à votre projet:

using System.Reactive.Linq;

someValues.ToObservable().Subscribe(x => list.Add(x + 1));

Cela a le même résultat final que l'utilisation précédente de ToList, mais est (en théorie) plus efficace, car il transmet les valeurs directement au délégué.

253
Mark Seemann

Les classes Array et List<T> ont déjà des méthodes ForEach, mais uniquement cette implémentation spécifique. (Notez que l'ancien est static, en passant).

Vous n'êtes pas sûr qu'elle offre un avantage considérable par rapport à une instruction foreach, mais vous pouvez écrire une méthode d'extension pour effectuer le travail pour tous les objets _IEnumerable<T>_.

_public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach (var item in source)
        action(item);
}
_

Cela permettrait au code exact que vous avez posté dans votre question de fonctionner comme vous le souhaitez.

92
Noldorin

Il n'y a rien d'intégré, mais vous pouvez facilement créer votre propre méthode d'extension pour le faire:

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    if (source == null) throw new ArgumentNullException("source");
    if (action == null) throw new ArgumentNullException("action");

    foreach (T item in source)
    {
        action(item);
    }
}
31
LukeH

La ligne officielle MS est "parce que ce n'est pas une opération fonctionnelle" (c'est-à-dire une opération avec état).

Ne pourriez-vous pas faire quelque chose comme:

list.Select( x => x+1 )

ou si vous en avez vraiment besoin dans une liste:

var someValues = new List<int>( list.Select( x => x+1 ) );
18
stusmith

Il n'y a pas d'extension Linq ForEach. Toutefois, la classe List comporte une méthode ForEach si vous souhaitez utiliser directement List.

Pour ce que cela vaut, la syntaxe standard foreach vous donnera les résultats que vous voulez et il est probablement plus facile à lire:

foreach (var x in someValues)
{
    list.Add(x + 1);
}

Si vous êtes catégorique, vous voulez une extension de style Linq. il est trivial de le mettre en œuvre vous-même.

public static void ForEach<T>(this IEnumerable<T> @this, Action<T> action)
{
   foreach (var x in @this)
      action(x);
}
4
dustyburwell

Il n'y a rien de tel dans Linq standard, mais il y a un opérateur ForEach dans MoreLinq .

3