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
Réponses
Trop de publicités?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);
}
}
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.
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.