51

Possible Duplicate:
Why is there not a ForEach extension method on the IEnumerable interface?

EDIT

For reference, here's the blog post which eric referred to in the comments

https://ericlippert.com/2009/05/18/foreach-vs-foreach/

ORIG

More of a curiosity I suppose but one for the C# Specification Savants...

Why is it that the ForEach() clause doesn't work (or isn't available) for use on IQueryable/IEnumerable result sets...

You have to first convert your results ToList() or ToArray() Presumably theres a technical limitation to the way C# iterates IEnumerables Vs. Lists... Is it something to do with the Deferred Execution's of IEnumerables/IQuerable Collections. e.g.

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));
Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
Eoin Campbell
  • 43,500
  • 17
  • 101
  • 157
  • 5
    I'd write `ForEach(uac => ProcessUserAgentString(uas))` as `ForEach(ProcessUserAgentString)`. – Mehrdad Afshari May 13 '09 at 16:54
  • 1
    What's the problem with a conventional for-each loop? foreach (var uas in UserAgentStrings) ProcessUserAgentString(uas); – Dario May 13 '09 at 16:54
  • Theres no problem... Like I said, it was more of a curiousity why the convention was available to use on Arrays/Lists but not on IQueryables/IEnumerables and as Eric Lippert pointed out below, it's a completely philosophical choice by the dev team and not for any technical reasons – Eoin Campbell May 13 '09 at 17:02
  • See also http://stackoverflow.com/questions/200574/linq-equivalent-of-foreach-for-ienumerablet – goodeye Jun 27 '12 at 01:41
  • Here's an alternative idea of how this *could* be possible: https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/16501309-shorthand-to-execute-method-in-foreach-loop – HappyNomad Oct 06 '16 at 06:32
  • Here is the updated link as the blogs.msdn link is dead: https://learn.microsoft.com/en-us/archive/blogs/ericlippert/foreach-vs-foreach – Raj Rao Feb 04 '20 at 13:56

1 Answers1

15

It's perfectly possible to write a ForEach extension method for IEnumerable<T>.

I'm not really sure why it isn't included as a built-in extension method:

  • Maybe because ForEach already existed on List<T> and Array prior to LINQ.
  • Maybe because it's easy enough to use a foreach loop to iterate the sequence.
  • Maybe because it wasn't felt to be functional/LINQy enough.
  • Maybe because it isn't chainable. (It's easy enough to make a chainable version that yields each item after performing an action, but that behaviour isn't particularly intuitive.)

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);
    }
}
LukeH
  • 263,068
  • 57
  • 365
  • 409