web-dev-qa-db-fra.com

Expression Lambda à l'aide de la clause Foreach

Duplicata possible:
Pourquoi n'y a-t-il pas de méthode d'extension ForEach sur l'interface IEnumerable?

[~ # ~] modifier [~ # ~]

Pour référence, voici le billet de blog auquel eric a fait référence dans les commentaires

http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx

[~ # ~] orig [~ # ~]

Plus une curiosité, je suppose, mais une pour les Savants de spécification C # ...

Pourquoi la clause ForEach () ne fonctionne-t-elle pas (ou n'est-elle pas disponible) pour une utilisation sur les jeux de résultats IQueryable/IEnumerable ...

Vous devez d'abord convertir vos résultats ToList () ou ToArray (). Il y a probablement une limitation technique à la façon dont C # itère IEnumerables Vs. Listes ... Est-ce quelque chose à voir avec l'exécution différée des collections IEnumerables/IQuerable. par exemple.

var userAgentStrings = uasdc.UserAgentStrings
    .Where<UserAgentString>(p => p.DeviceID == 0 && 
                            !p.UserAgentString1.Contains("msie"));
//WORKS            
userAgentStrings.ToList().ForEach(uas => ProcessUserAgentString(uas));         

//WORKS
Array.ForEach(userAgentStrings.ToArray(), uas => ProcessUserAgentString(uas));

//Doesn't WORK
userAgentStrings.ForEach(uas => ProcessUserAgentString(uas));
50
Eoin Campbell

Quelle étonnante coïncidence, je viens d'écrire un article de blog sur cette question. Il seraa été publié le 18 mai . Il n'y a aucune raison technique pour laquelle nous (ou vous!) Ne pourrions pas faire cela. Les raisons pour lesquelles ce n'est pas le cas sont philosophiques. Voir mon blog la semaine prochaine pour mon argument.

57
Eric Lippert

Il est parfaitement possible d'écrire une méthode d'extension ForEach pour IEnumerable<T>.

Je ne sais pas vraiment pourquoi il n'est pas inclus en tant que méthode d'extension intégrée:

  • Peut-être parce que ForEach existait déjà sur List<T> et Array avant LINQ.
  • Peut-être parce qu'il est assez facile d'utiliser une boucle foreach pour itérer la séquence.
  • Peut-être parce qu'il n'était pas jugé suffisamment fonctionnel/LINQy.
  • Peut-être parce qu'il n'est pas chaînable. (Il est assez facile de créer une version chaînable qui yields chaque élément après avoir effectué une action, mais ce comportement n'est pas particulièrement intuitif.)

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