62

I have an Enumerable<T> and am looking for a method that allows me to execute an action for each element, kind of like Select but then for side-effects. Something like:

string[] Names = ...;
Names.each(s => Console.Writeline(s));

or

Names.each(s => GenHTMLOutput(s));   
// (where GenHTMLOutput cannot for some reason receive the enumerable itself as a parameter)

I did try Select(s=> { Console.WriteLine(s); return s; }), but it wasn't printing anything.

MicroVirus
  • 5,324
  • 2
  • 28
  • 53
Daniel Magliola
  • 30,898
  • 61
  • 164
  • 243
  • Possible duplicate of [Apply function to all elements of collection through LINQ](http://stackoverflow.com/questions/823532/apply-function-to-all-elements-of-collection-through-linq) – Michael Freidgeim Aug 15 '16 at 08:25

10 Answers10

72

A quick-and-easy way to get this is:

Names.ToList().ForEach(e => ...);
Jay Bazuzi
  • 45,157
  • 15
  • 111
  • 168
  • 7
    ToList() will evaluate every node in the IEnumerable, meaning that any lazy evaluation is done at that point. I'd rather leave this as late as possible by making my own extensions method. – Jeff Yates Feb 09 '09 at 18:20
  • 3
    Sorry guys, I chose the unpopular method. I understand the downside of losing lazy evaluation, but when i'm doing the ForEach on my list, I want it to happen NOW anyway, so there's not much advantage is lazying off anymore. – Daniel Magliola Feb 09 '09 at 19:00
  • The extension method IS better, and it's probably faster too, but this is "kind of" more standard for me, and short enough to type. Thanks Jay! – Daniel Magliola Feb 09 '09 at 19:01
  • 7
    There is a big problem with this. If you do ToList then all of the objects *must* exist in memory at once. If the source is a DB then at least using IEnumerable your objects may be unloaded once finished. Use ToList and you can run out of memory for large data sets! DON'T USE IT! – Peter Morris Feb 09 '09 at 22:16
  • 3
    Yes, there are plenty of drawbacks to this approach, but I'm amazed at how often they aren't a problem, and this simple approach works just fine. Fact is, most of my sequences are < 100 elements. (Maybe you're doing more interesting programming than I do.) – Jay Bazuzi Feb 10 '09 at 01:26
  • Peter, that's an EXCELLENT point. It doesn't really apply to my situation (and probably never will), but it's a good thing to keep in mind, it might become a problem in certain situations – Daniel Magliola Feb 10 '09 at 12:29
  • If the enumerable is already an array or list, using the Array or List ForEach is going to be considerably faster than a simple ForEach extension. Such a ForEach should check to see if it can index and use a for loop instead of foreach since apparently the compiler/runtime won't optimize. – MichaelGG Feb 11 '09 at 17:49
  • @JeffYates The entire point of performing an action with side-effects is that the execution happens *right now* and is not lazily delayed -- for lazy, `Select` already exists. – MicroVirus May 13 '16 at 17:34
31

Disclaimer: This post no longer resembles my original answer, but rather incorporates the some seven years experience I've gained since. I made the edit because this is a highly-viewed question and none of the existing answers really covered all the angles. If you want to see my original answer, it's available in the revision history for this post.


The first thing to understand here is C# linq operations like Select(), All(), Where(), etc, have their roots in functional programming. The idea was to bring some of the more useful and approachable parts of functional programming to the .Net world. This is important, because a key tenet of functional programming is for operations to be free of side effects. It's hard to understate this. However, in the case of ForEach()/each(), side effects are the entire purpose of the operation. Adding each() or ForEach() is not just outside the functional programming scope of the other linq operators, but in direct opposition to them.

But I understand this feels unsatisfying. It may help explain why ForEach() was omitted from the framework, but fails to address the real issue at hand. You have a real problem you need to solve. Why should all this ivory tower philosophy get in the way of something that might be genuinely useful?

Eric Lippert, who was on the C# design team at the time, can help us out here. He recommends using a traditional foreach loop:

[ForEach()] adds zero new representational power to the language. Doing this lets you rewrite this perfectly clear code:

foreach(Foo foo in foos){ statement involving foo; }

into this code:

foos.ForEach(foo=>{ statement involving foo; });

His point is, when you look closely at your syntax options, you don't gain anything new from a ForEach() extension versus a traditional foreach loop. I partially disagree. Imagine you have this:

 foreach(var item in Some.Long(and => possibly)
                         .Complicated(set => ofLINQ)
                         .Expression(to => evaluate))
 {
     // now do something
 } 

This code obfuscates meaning, because it separates the foreach keyword from the operations in the loop. It also lists the loop command prior to the operations that define the sequence on which the loop operates. It feels much more natural to want to have those operations come first, and then have the the loop command at the end of the query definition. Also, the code is just ugly. It seems like it would be much nicer to be able to write this:

Some.Long(and => possibly)
   .Complicated(set => ofLINQ)
   .Expression(to => evaluate)
   .ForEach(item => 
{
    // now do something
});

However, even here, I eventually came around to Eric's point of view. I realized code like you see above is calling out for an additional variable. If you have a complicated set of LINQ expressions like that, you can add valuable information to your code by first assigning the result of the LINQ expression to a new well-named variable:

var queryForSomeThing = Some.Long(and => possibly)
                        .Complicated(set => ofLINQ)
                        .Expressions(to => evaluate);
foreach(var item in queryForSomeThing)
{
    // now do something
}

This code feels more natural. It puts the foreach keyword back next to the rest of the loop, and after the query definition. Most of all, the variable name can add new information that will be helpful to future programmers trying to understand the purpose of the LINQ query. Again, we see the desired ForEach() operator really added no new expressive power to the language.

However, we are still missing two features of a hypothetical ForEach() extension method:

  1. It's not composable. I can't add a further .Where() or GroupBy() or OrderBy() after a foreach loop inline with the rest of the code, without creating a new statement.
  2. It's not lazy. These operations happen immediately. It doesn't allow me to, say, have a form where a user chooses an operation as one field in a larger screen that is not acted on until the user presses a command button. This form might allow the user to change their mind before executing the command. This is perfectly normal (easy even) with a LINQ query, but not as simple with a foreach.

(FWIW, most naive .ForEach() implementations also have these issues. But it's possible to craft one without them.)

You could, of course, make your own ForEach() extension method. Several other answers have implementations of this method already; it's not all that complicated. However, I feel like it's unnecessary. There's already an existing method that fits what we want to do from both semantic and operational standpoints. Both of the missing features above can be addressed by use of the existing Select() operation.

Select() fits the kind of transformation or projection described by both of the examples above. Keep in mind, though, that I would still avoid creating side effects. The call to Select() should return either new objects or projections from the originals. This can sometimes be aided through the use of an anonymous type or dynamic object (if and only if necessary). If you need the results to persist in, say, an original list variable, you can always call .ToList() and assign it back to your original variable. I'll add here that I prefer working with IEnumerable<T> variables as much as possible over more concrete types.

myList = myList.Select(item => new SomeType(item.value1, item.value2 *4)).ToList();

In summary:

  1. Just stick with foreach most of the time.
  2. When foreach really won't do (which probably isn't as often as you think), use Select()
  3. When you need to use Select(), you can still generally avoid (program-visible) side effects, possibly by projecting to an anonymous type.
  4. Avoid the crutch of calling ToList(). You don't need it as much as you might think, and it can have significant negative consequence for performance and memory use.
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • 1
    Downvoted: This will only process all items if the predicate continues to return "true". If you are executing a method which returns a boolean it could be very easy to accidentally introduce an error without realising it. – Peter Morris Feb 09 '09 at 18:11
  • @PeterMorris I believe he meant that you can use the lambda to do whatever you want and when you are done executing your code simply return true. In this case you will probably want to use a statement lambda which require curly braces. Not a bad solution if you only want to use built in functionality and retain lazy evaluation. – Alex Jorgenson May 10 '16 at 13:10
  • @AlexJorgenson .All() is supposed to be side-effect free, it's not a good way to go about this kind of thing as its purpose is for something else – Peter Morris May 11 '16 at 15:55
  • 1
    @Peter Morris Definitely. I wrote this post before I had fully come to terms with that. I had an understanding of the linq operators, but less so of the functional programming roots behind them. Today, I'd agree with [Eric Lippert's recommendation to just use `foreach`.](https://blogs.msdn.microsoft.com/ericlippert/2009/05/18/foreach-vs-foreach/) – Joel Coehoorn May 11 '16 at 16:59
  • My only complaint is the `foreach` semantics are a little weird in this situation. It puts the loop command before the query on which the loop operates. A ForEach() extension puts things in a better order: do all this filtering/sorting/etc, and **after** all that perform some operation on whatever is left. Even here, I take it as an indication I should assign my linq operations to some variable, and then use this variable for the foreach loop. Then the variable name can add valuable information to the code about what some otherwise-complex linq instructions are intended to accomplish. – Joel Coehoorn May 11 '16 at 17:09
  • 1
    Oh... the other complaint with foreach is that is doesn't return the sequence. But, if you need that, I'd look into a `Select()` that returns a new object (no side effects) rather than an `All()`. Seven years is a long time ;) – Joel Coehoorn May 11 '16 at 18:13
  • I'm thinking I need to edit some of this into my answer. In February of 2009 linq was not much more than a year old, and few understood it that well. I don't see ANY of the answers in this question really covering all of this nuance that well, but the question has nearly 15000 views – Joel Coehoorn May 11 '16 at 18:17
  • @JoelCoehoorn Upvoted because the answer is accurate and informative as to why. If you feel like adding more, it might be worth noting that these are also side-effect free because they can be converted to DB queries etc. The purpose of ToList is to ensure the expression is evaluated and the result converted to an IEnumerable for client-side processing (i.e. not in the DB Server) so that only the operations supported server-side (DB Server) are available to LINQ at a specific time. – Peter Morris May 12 '16 at 09:19
  • *It's hard to understate this.* -- Actually, that's easy, but I understand what you mean ;) – Gert Arnold Apr 02 '23 at 17:55
21

You are looking for the ever-elusive ForEach that currently only exists on the List generic collection. There are many discussions online about whether Microsoft should or should not add this as a LINQ method. Currently, you have to roll your own:

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

While the All() method provides similar abilities, it's use-case is for performing a predicate test on every item rather than an action. Of course, it can be persuaded to perform other tasks but this somewhat changes the semantics and would make it harder for others to interpret your code (i.e. is this use of All() for a predicate test or an action?).

Jeff Yates
  • 61,417
  • 20
  • 137
  • 189
  • 1
    I'd prefer it if it would be added. Including an overload that takes a Func action and returns IEnumerable. Even if that can be done with Select already. – peSHIr Feb 09 '09 at 18:13
  • You can certainly write one to do that, if that is your use-case. – Jeff Yates Feb 09 '09 at 18:13
  • 2
    Using All would be a bad idea - If any of those Func's returned false, then execution would end. – Amy B Feb 09 '09 at 19:15
  • Yup, that's another great reason not to use it. – Jeff Yates Feb 10 '09 at 06:05
  • 1
    This is not lazy though, is it? So it would evaluate the query immediately. No real advantage over just plain foreach. – kristianp Mar 14 '19 at 01:42
  • @kristianp No, it will not evaluate immediately. The only advantage with this approach is that you will have an extension method you could later use wherever there is an IEnumerable. In other words, this will become a "syntactic sugar" to be used as a shortcut, but that is the idea with extension methods anyways. – Alfredo A. Nov 28 '19 at 19:23
6

Unfortunately there is no built-in way to do this in the current version of LINQ. The framework team neglected to add a .ForEach extension method. There's a good discussion about this going on right now on the following blog.

http://blogs.msdn.com/kirillosenkov/archive/2009/01/31/foreach.aspx

It's rather easy to add one though.

public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action) {
  foreach ( var cur in enumerable ) {
    action(cur);
  }
}
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • To be able to use this in concatenated LinQ sequence consider returning enumerable as IEnumerable. For example: ...Select(...).ForEach(...).Where(...).Distinct(); – Harald Coppoolse May 11 '15 at 13:25
5

You cannot do this right away with LINQ and IEnumerable - you need to either implement your own extension method, or cast your enumeration to an array with LINQ and then call Array.ForEach():

Array.ForEach(MyCollection.ToArray(), x => x.YourMethod());

Please note that because of the way value types and structs work, if the collection is of a value type and you modify the elements of the collection this way, it will have no effect on the elements of the original collection.

Tamas Czinege
  • 118,853
  • 40
  • 150
  • 176
3

Because LINQ is designed to be a query feature and not an update feature you will not find an extension which executes methods on IEnumerable<T> because that would allow you to execute a method (potentially with side effects). In this case you may as well just stick with

foreach(string name in Names)
Console.WriteLine(name);

Peter Morris
  • 20,174
  • 9
  • 81
  • 146
2

Using Parallel Linq:

Names.AsParallel().ForAll(name => ...)

Chris Xue
  • 2,317
  • 1
  • 25
  • 21
1

Well, you can also use the standard foreach keyword, just format it into a oneliner:

foreach(var n in Names.Where(blahblah)) DoStuff(n);

Sorry, thought this option deserves to be here :)

Serge Shultz
  • 5,888
  • 3
  • 27
  • 17
0

There is a ForEach method off of List. You could convert the Enumerable to List by calling the .ToList() method, and then call the ForEach method off of that.

Alternatively, I've heard of people defining their own ForEach method off of IEnumerable. This can be accomplished by essentially calling the ForEach method, but instead wrapping it in an extension method:

public static class IEnumerableExtensions
{
    public static IEnumerable<T> ForEach<T>(this IEnumerable<T> _this, Action<T> del)
    {
        List<T> list = _this.ToList();
        list.ForEach(del);
        return list;
    }
}
David Morton
  • 16,338
  • 3
  • 63
  • 73
  • That would force a complete sequence evaluation taking up memory for each element of the temporary List. I'd go with the extension method on IEnumerable any time I can get away with to preserve the lazy evaluation properties as long as possible. – peSHIr Feb 09 '09 at 18:11
-1

As mentioned before ForEach extension will do the fix.

My tip for the current question is how to execute the iterator

[I did try Select(s=> { Console.WriteLine(s); return s; }), but it wasn't printing anything.]

Check this

_= Names.Select(s=> { Console.WriteLine(s); return 0; }).Count();

Try it!

Waleed A.K.
  • 1,596
  • 13
  • 13