55 votes

Pourquoi .ForEach () sur IList <T> et pas sur IEnumerable <T> ?

Double Possible:
Pourquoi n'est-il pas un ForEach de la méthode d'extension sur l'interface IEnumerable?

J'ai remarqué lors de l'écriture de LINQ-y code .ForEach() est une belle langage à utiliser. Par exemple, voici un morceau de code qui prend les entrées ci-dessous, et le produit de ces sorties:

{ "One" } => "One"
{ "One", "Two" } => "One, Two"
{ "One", "Two", "Three", "Four" } => "One, Two, Three and Four";

Et le code:

private string InsertCommasAttempt(IEnumerable<string> words)
{
    List<string> wordList = words.ToList();
    StringBuilder sb = new StringBuilder();
    var wordsAndSeparators = wordList.Select((string word, int pos) =>
        {
            if (pos == 0) return new { Word = word, Leading = string.Empty };
            if (pos == wordList.Count - 1) return new { Word = word, Leading = " and " };
            return new { Word = word, Leading = ", " };
        });

    wordsAndSeparators.ToList().ForEach(v => sb.Append(v.Leading).Append(v.Word));
    return sb.ToString();
}

Remarque l'intervenu .ToList() avant de l' .ForEach() sur la deuxième à la dernière ligne.

Pourquoi est-ce que .ForEach() n'est pas disponible comme une extension de la méthode sur IEnumerable? Avec un exemple comme ceci, il semble juste bizarre.

Merci d'avance,

Dave

40voto

Samuel Points 21085

Parce qu' ForEach(Action) existait avant IEnumerable<T> existé.

Depuis, il n'a pas été ajouté avec les autres méthodes d'extension, on peut supposer que le C# concepteurs senti que c'était une mauvaise conception et préfèrent l' foreach construire.


Edit:

Si vous le souhaitez, vous pouvez créer votre propre méthode d'extension, de ne pas remplacer un List<T> , mais il va travailler pour toute autre classe qui implémente IEnumerable<T>.

public static class IEnumerableExtensions
{
  public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
  {
    foreach (T item in source)
      action(item);
  }
}

40voto

Justin R. Points 10122

Selon l'un des langage C# designers, Eric Lippert, c'est surtout pour des raisons philosophiques. Vous devriez lire l'ensemble du post, mais voici l'essentiel à savoir pour autant que je suis concerné:

Je suis philosophiquement opposés à la pour obtenir une telle méthode, pour deux raisons.

La première raison est que cela viole la programmation fonctionnelle les principes que tous les autres de la séquence les opérateurs sont basées sur. Clairement l' seul but d'un appel à cette méthode c'est de provoquer des effets secondaires.

Le but d'une expression est à calculer une valeur, de ne pas causer un côté effet. Le but de la déclaration est à cause d'un effet secondaire. Le site d'appel de cette chose aurait l'air d'un tas comme une expression (même si, certes, depuis la méthode est vide-retour, l'expression pourrait être utilisé uniquement dans une "déclaration l'expression" contexte.)

Il n'est pas bien assis avec moi pour faire de le seul et unique opérateur de séquence c'est utile uniquement pour son côté des effets.

La deuxième raison est que cela ajoute zéro nouveau pouvoir de représentation pour la langue.

5voto

Joel Coehoorn Points 190579

Parce que ForEach() sur un IEnumerable est juste une normale pour chaque boucle comme ceci:

 for each T item in MyEnumerable
{
    // Action<T> goes here
}
 

3voto

Surya Points 2606

Je ne fais que deviner, mais mettre foreach sur IEnumerable rendrait les opérations plus douloureuses. Aucune des méthodes d'extension "disponibles" ne provoque d'effets secondaires, mettre une méthode impérative telle que foreach boucherait l'api, je suppose. En outre, foreach initialiserait la collection paresseuse.

Personnellement, j'ai repoussé la tentation d'ajouter simplement la mienne, juste pour que les fonctions sans effets secondaires soient séparées de celles comportant des effets secondaires.

3voto

Joshua Belden Points 3492

ForEach n'est pas sur IList c'est sur la liste. Vous utilisiez la liste concrète dans votre exemple.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X