868

I'd like to do the equivalent of the following in LINQ, but I can't figure out how:

IEnumerable<Item> items = GetItems();
items.ForEach(i => i.DoStuff());

What is the real syntax?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
tags2k
  • 82,117
  • 31
  • 79
  • 106
  • 3
    There is [MoreLINQ](https://code.google.com/p/morelinq/) which has a [`ForEach` extension](https://code.google.com/p/morelinq/wiki/OperatorsOverview). – Uwe Keim Jul 15 '14 at 10:02
  • 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:29
  • 4
    Whilst not very sexy, this fits on one line without creating a copy via ToList - `foreach (var i in items) i.Dostuff();` – James Westgate Jun 22 '18 at 13:02
  • 3
    Some of these links are dead! What was the article that was up-voted so much! – Warren Mar 31 '20 at 07:57

22 Answers22

1044

There is no ForEach extension for IEnumerable; only for List<T>. So you could do

items.ToList().ForEach(i => i.DoStuff());

Alternatively, write your own ForEach extension method:

public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
    foreach(T item in enumeration)
    {
        action(item);
    }
}
huysentruitw
  • 27,376
  • 9
  • 90
  • 133
Fredrik Kalseth
  • 13,934
  • 4
  • 25
  • 17
  • I used to have a method like this in my code, but really ToList().ForEach() solves the problem and I feel that Jon's answer, below, is more correct. – cfeduke Apr 17 '09 at 14:39
  • 264
    Be careful with ToList(), because ToList() creates a copy of the sequence, which could cause performance and memory issues. – decasteljau Aug 14 '09 at 12:37
  • 17
    There are few reasons why ".Foreach()" will be better. 1. Multi-threading, possible by PLINQ. 2. Exceptions, you may want to collect all exception in the loop and throw it at once; and they are noise codes. – Dennis C Feb 07 '10 at 07:06
  • I wonder if there is a convenient way to make a ForEach implementation like this that can have deferred execution? Might be handy although I think it is probably worse as far as the concern about side effects. – jpierson Mar 30 '10 at 21:40
  • 15
    PLINQ uses ForAll not ForEach, which is why you wouldn't use ForEach. – user7116 Jul 17 '10 at 23:21
  • 3
    Note - because of the copy that the ToList performs, this does will not work for cases where you want to perform an operation that alters the state of each item in the IEnumerable. – Michael Lang May 12 '11 at 16:38
  • 1
    @jpierson the extension method that Fredrik wrote as alternatively is deferred. IMHO the "alternative" should be listed as the preferred. – CodeMonkeyKing Sep 20 '11 at 20:50
  • what would you consider an alternative to the foreach if you needed the items in the list to return a value i.e. it will perform a Func<> and no an Action .? – eran otzap Dec 04 '11 at 16:44
  • 2
    The more cleaner and readable approach is to use the extension method opposed to the ToList().ForEach(). Although the latter is a quick fix, the ToList() part does not have any value with regards to the functionality of the code. It is sitting in the middle merely as an adapter, which makes the code looks more confusing at first sight. – Ε Г И І И О Mar 21 '12 at 05:21
  • 4
    The first example is terrible, but the second example I think is definitely useful for readability when used in the right situation. Particularly in cases when you can pass just a method, without using the lambda notation. Ex: `sequence.ForEach(doSomething);` instead of: `foreach (Item item in sequence) doSomething(item);` This can make a huge difference if you have a lot of these that can be simplified. – Dave Cousineau Apr 08 '12 at 03:33
  • 14
    You should return an `IENumerable` in the extension method. Like: `public static IEnumerable ForAll(this IEnumerable numeration, Action action) { foreach (T item in enumeration) { action(item); } return enumeration; }` – Kees C. Bakker Dec 05 '12 at 15:29
  • 30
    Note that in the first case the developer 1) saves almost no typing and 2) unnecessarily allocates memory to store the entire sequence as a list before throwing it away. Think before you LINQ – Mark Sowul Jul 29 '13 at 04:21
  • I added an example to this post for when a property of a collection needs to be processed by a method. – Scott Nimrod Sep 11 '14 at 00:20
  • 1
    @KeesC.Bakker Agreed, this would allow chaining `items.ForAll(i => i.Name = "Reset Value").SomethingElse(...` as well as mutate and pass into some subsequent method. – Luke Puplett Aug 13 '15 at 16:11
  • #1 also loops the list twice. – Matthew Whited May 03 '17 at 15:46
  • be wary of NOT introducing a variable ;-) – John Erbynn Feb 12 '21 at 11:25
  • 1
    Why should we return `IENumerable` @KeesC.Bakker? – Denny Oct 13 '21 at 09:29
  • what does the action parameter do? – Golden Lion Nov 15 '22 at 18:23
423

Fredrik has provided the fix, but it may be worth considering why this isn't in the framework to start with. I believe the idea is that the LINQ query operators should be side-effect-free, fitting in with a reasonably functional way of looking at the world. Clearly ForEach is exactly the opposite - a purely side-effect-based construct.

That's not to say this is a bad thing to do - just thinking about the philosophical reasons behind the decision.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 3
    For reference, this question poses the same question, and gets input from "the powers that be": http://stackoverflow.com/questions/858978/lambda-expression-using-foreach-clause – Benjol Jun 04 '09 at 13:11
  • 9
    However, there's one very useful thing that LINQ functions typically provide that foreach () doesn't - the anonymous function taken by Linq functions can also take an index as a parameter, whereas with foreach you must rebuild the classic for (int i..) construct. And functional languages have to allow iteration that has side effects - otherwise you could never do one iota of work with them :) I'd like to point out that the typical functional method would be to return the original enumerable unchanged. – Walt W Sep 01 '10 at 17:22
  • @Walt: If a typical functional method returned the original enumerable and *didn't* have side-effects (which *typical* functional methods don't) then it would have no effect at all. Perhaps you could clarify your comment? – Jon Skeet Sep 01 '10 at 17:33
  • 1
    @Jon Skeet: Essentially, with any language, you're always going to have to output or otherwise pass along some material to "get work done" (output to file, progress inform, whatever). That's where foreach constructs have a place in a functional environment - performing those sorts of actions. So saying that it doesn't have side effects is the same as saying you don't need a foreach. – Walt W Sep 01 '10 at 18:13
  • 1
    @Jon Skeet - As for clarifying my post a bit, perhaps I should rephrase the last sentence: "I'd like to point out that the typical functional _approach with a foreach_ would be to return the original enumerable unchanged" – Walt W Sep 01 '10 at 18:14
  • 4
    @Walt: I'm still not sure I agree, partly because a typical truly functional approach wouldn't *use* foreach like this... it would use a functional approach more like LINQ, creating a new sequence. – Jon Skeet Sep 01 '10 at 19:12
  • 1
    @Jon: Well, that I agree with; hence the "saying it doesn't have side effects is the same as saying you don't need a foreach". But LINQ isn't academically functional, is it? I'd consider it a practical functional construct within C#. Practicality (unfortunately?) requires side effects... And so I don't believe it would be philosophically inappropriate to add this construct to LINQ just because of side effects. It might be more appropriate, however, to provide a method for fetching the index in the body of a foreach. But it would be nice to have in both places. – Walt W Sep 01 '10 at 19:49
  • 2
    @Walt: Practicality doesn't need side effects *everywhere* though. Usually I'd use LINQ for the side-effect-free part, and then a `foreach` loop for the side-effecting part of the code. If you want the index in `foreach`, you can either use `foreach (var pair in sequence.Select((value, index) => new { value, index }))` or use my SmartEnumerable class from MiscUtil which is much the same: http://www.yoda.arachsys.com/csharp/miscutil/usage/smartenumerable.html – Jon Skeet Sep 01 '10 at 20:03
  • 1
    @Jon: Adding a ForEach to LINQ doesn't encourage using it everywhere. You are right that they don't need to be everywhere though. And I know there's equivalent user code; personally I'd prefer just using an for() loop than constructing a new list of completely new objects just to access the index. Language / official library support would be nice. But yes, user code is a currently viable option. – Walt W Sep 01 '10 at 20:35
  • 13
    @Stephen Swensen: yes, F# has Seq.iter, but F# also has immutable data structures. when using Seq.iter on these, the original Seq isn't modified; a new Seq with the side-effected elements is returned. – Anders Feb 09 '11 at 14:38
  • 8
    @Anders - `Seq.iter` doesn't return anything, let alone a new seq with side-effected elements. It really is just about side-effects. You may be thinking of `Seq.map`, because `Seq.iter` is precisely equivalent to a `ForEach` extension method on `IEnumerabe<_>`. – Joel Mueller Mar 03 '11 at 00:18
  • 1
    @Jon: I do believe your answer is helpful however you failed to mention when you need to close over the loop variable. One might consider "ForEach" instead of "foreach" here. See my answer http://stackoverflow.com/questions/200574/linq-equivalent-of-foreach-for-ienumerablet/7275403#7275403. I found myself in this situation today when using moq in a unit test. I actually came here to understand why "ForEach" wasn't provided for IEnumerable before implementing it myself. – drstevens Sep 01 '11 at 20:36
  • 2
    @drstevens: I think I'd probably still use `foreach` even then, to be honest. – Jon Skeet Sep 01 '11 at 20:44
  • 2
    I read the Eric Lippert article, and read through the comments on this Q&A, but still don't understand why it's okay for `IList.ForEach` to cause side-effects while `IEnumerable.ForEach` should not be allowed to cause side-effects. I agree with all the other arguments against a `ForEach`, but `ForEach` would allow for a fluent API. Can someone explain why side-effects are bad for `IEnumerable` but not for `IList`? – crush Nov 13 '15 at 21:46
  • @crush Not precisely an answer, but note the UPDATE at the bottom of Lippert's blog...[Metro apparently removed `List.ForEach`](https://social.msdn.microsoft.com/Forums/en-US/758f7b98-e3ce-41e5-82a2-109f1df446c2/where-is-listtforeach?forum=winappswithcsharp): "*While the method seems simple it has a number of potential problems when the list gets mutated by the method passed to ForEach. Instead it is recommended that you simply use a foreach loop.*" -Wes Haggard, BCL Team. That's kind of a practical example of the philosophy "against" side effects Skeet explains. – ruffin Apr 19 '16 at 13:53
  • Working link to Eric Lipperts article from @AlexAngas's comment: https://web.archive.org/web/20190118075220/https://blogs.msdn.microsoft.com/ericlippert/2009/05/18/foreach-vs-foreach/ – Bouke Mar 11 '20 at 07:30
  • *That's not to say this is a bad thing to do*. 12 years later, I would strongly disagree. A `ForEach` extension on `IEnumerable` is disastrous (see my answer), and the community deserves to know. – l33t Jun 30 '20 at 17:46
  • 2
    @l33t: I think "disastrous" is a *massive* overstatement, and you may well find that the performance difference becomes insignificant when you actually *do* something in the loop. I don't particularly care how much time it takes to do *nothing*. – Jon Skeet Jun 30 '20 at 18:09
  • @JonSkeet You're both right and wrong :) It depends on the context, obviously. If some Unity developer comes here and decides to copy a nice-to-have extension method, there will be unhappy faces when their game suddenly stutters due to GC. – l33t Jun 30 '20 at 22:14
  • 1
    @l33t: So yes, just as with *every piece of code you ever find on the internet* you need to check whether it's appropriate to use in your context. I have no issue with you raising the performance differences between the two approaches, but there's no need for hyperbole. Note that doing anything with LINQ will have the same performance characteristic - are you going to denounce LINQ as "disastrous" as well? – Jon Skeet Jul 01 '20 at 06:44
  • @JonSkeet Yes, in fact :D. It's a complex subject though. I'll blog about it some day, and get back to you. – l33t Jul 01 '20 at 07:46
41

Update 7/17/2012: Apparently as of C# 5.0, the behavior of foreach described below has been changed and "the use of a foreach iteration variable in a nested lambda expression no longer produces unexpected results." This answer does not apply to C# ≥ 5.0.

@John Skeet and everyone who prefers the foreach keyword.

The problem with "foreach" in C# prior to 5.0, is that it is inconsistent with how the equivalent "for comprehension" works in other languages, and with how I would expect it to work (personal opinion stated here only because others have mentioned their opinion regarding readability). See all of the questions concerning "Access to modified closure" as well as "Closing over the loop variable considered harmful". This is only "harmful" because of the way "foreach" is implemented in C#.

Take the following examples using the functionally equivalent extension method to that in @Fredrik Kalseth's answer.

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

Apologies for the overly contrived example. I'm only using Observable because it's not entirely far fetched to do something like this. Obviously there are better ways to create this observable, I am only attempting to demonstrate a point. Typically the code subscribed to the observable is executed asynchronously and potentially in another thread. If using "foreach", this could produce very strange and potentially non-deterministic results.

The following test using "ForEach" extension method passes:

[Test]
public void ForEachExtensionWin()
{
    //Yes, I know there is an Observable.Range.
    var values = Enumerable.Range(0, 10);

    var observable = Observable.Create<Func<int>>(source =>
                            {
                                values.ForEach(value => 
                                    source.OnNext(() => value));

                                source.OnCompleted();
                                return () => { };
                            });

    //Simulate subscribing and evaluating Funcs
    var evaluatedObservable = observable.ToEnumerable().Select(func => func()).ToList();

    //Win
    Assert.That(evaluatedObservable, 
        Is.EquivalentTo(values.ToList()));
}

The following fails with the error:

Expected: equivalent to < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 > But was: < 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 >

[Test]
public void ForEachKeywordFail()
{
    //Yes, I know there is an Observable.Range.
    var values = Enumerable.Range(0, 10);

    var observable = Observable.Create<Func<int>>(source =>
                            {
                                foreach (var value in values)
                                {
                                    //If you have resharper, notice the warning
                                    source.OnNext(() => value);
                                }
                                source.OnCompleted();
                                return () => { };
                            });

    //Simulate subscribing and evaluating Funcs
    var evaluatedObservable = observable.ToEnumerable().Select(func => func()).ToList();

    //Fail
    Assert.That(evaluatedObservable, 
        Is.EquivalentTo(values.ToList()));
}
Community
  • 1
  • 1
drstevens
  • 2,903
  • 1
  • 21
  • 30
  • What does the resharper warning say? – reggaeguitar Jun 11 '19 at 19:25
  • 1
    @reggaeguitar I haven't used C# in 7 or 8 years, since before C# 5.0 was released, which changed the behavior described here. At the time it gave this warning https://stackoverflow.com/questions/1688465/resharper-warning-access-to-modified-closure. I doubt that it still warns on this though. – drstevens Jun 12 '19 at 20:27
39

You could use the FirstOrDefault() extension, which is available for IEnumerable<T>. By returning false from the predicate, it will be run for each element but will not care that it doesn't actually find a match. This will avoid the ToList() overhead.

IEnumerable<Item> items = GetItems();
items.FirstOrDefault(i => { i.DoStuff(); return false; });
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Rhames
  • 671
  • 5
  • 2
  • 14
    I agree too. It might be a clever little hack, but at first sight, this code isn't clear what it is doing, certainly in comparison to a standard foreach loop. – Connell Feb 07 '12 at 13:07
  • 33
    I had to downvote because while _technically_ correct, your future self and all your successors will hate you forever because instead of `foreach(Item i in GetItems()) { i.DoStuff();}` you took more characters and made it extremely confusing – Mark Sowul Jul 29 '13 at 04:23
  • 15
    Ok, but prolly a more readable hack: `items.All(i => { i.DoStuff(); return true; }` – nawfal Jun 19 '14 at 21:01
  • 8
    I know this is a fairly old post, but I had to downvote it also. I agree it's a clever trick, but it's not maintainable. At first glance it looks like it's doing something with the first item in the list only. This could easily cause more bugs in the future by coders misunderstanding how it functions and what it's supposed to be doing. – Lee Jan 12 '15 at 04:40
  • 1
    Maybe use this so intention is clear? `public static void ForEach(this IEnumerable enumeration, Action action) { enumeration.FirstOrDefault(item => { action(item); return false; }); }` – Don Mar 11 '15 at 22:28
  • 5
    This is side effect programming and IMHO discouraged. – Anish Jun 03 '15 at 21:40
  • 2
    Better create your own extension because this "hack" is too ugly with a little extra CPU cost. To be objective: It's a bad decision. – marciowb Aug 13 '15 at 17:40
  • 2
    @Don - I agree an extension method is clearer. But given that, why would one implement it using this confusing FirstOrDefault trick, rather than Fredrik's straightforward `foreach` implementation? – ToolmakerSteve Mar 03 '17 at 04:21
  • @nawfal I recently started using this syntax because it can be very useful when you first need to check `items` for nullity, so you just do `items?.All(i => { i.DoStuff(); return true; }` – user1832484 Nov 02 '20 at 14:52
  • @nawfal any motivation? – user1832484 Nov 02 '20 at 19:03
27

So many answers, yet ALL fail to pinpoint one very significant problem with a custom generic ForEach extension: Performance! And more specifically, memory usage and GC.

Consider the sample below. Targeting .NET Framework 4.7.2 or .NET Core 3.1.401, configuration is Release and platform is Any CPU.

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

class Program
{
    private static void NoOp(int value) {}

    static void Main(string[] args)
    {
        var list = Enumerable.Range(0, 10).ToList();
        for (int i = 0; i < 1000000; i++)
        {
            // WithLinq(list);
            // WithoutLinqNoGood(list);
            WithoutLinq(list);
        }
    }

    private static void WithoutLinq(List<int> list)
    {
        foreach (var item in list)
        {
            NoOp(item);
        }
    }

    private static void WithLinq(IEnumerable<int> list) => list.ForEach(NoOp);

    private static void WithoutLinqNoGood(IEnumerable<int> enumerable)
    {
        foreach (var item in enumerable)
        {
            NoOp(item);
        }
    }
}

At a first glance, all three variants should perform equally well. However, when the ForEach extension method is called many, many times, you will end up with garbage that implies a costly GC. In fact, having this ForEach extension method on a hot path has been proven to totally kill performance in our loop-intensive application.

Similarly, the weakly typed foreach loop will also produce garbage, but it will still be faster and less memory-intensive than the ForEach extension (which also suffers from a delegate allocation).

Strongly typed foreach: Memory usage

No allocations. No GC

Weakly typed foreach: Memory usage

enter image description here

ForEach extension: Memory usage

Lots of allocations. Heavy GC.

Analysis

For a strongly typed foreach the compiler is able to use any optimized enumerator (e.g. value based) of a class, whereas a generic ForEach extension must fall back to a generic enumerator which will be allocated on each run. Furthermore, the actual delegate will also imply an additional allocation.

You would get similar bad results with the WithoutLinqNoGood method. There, the argument is of type IEnumerable<int> instead of List<int> implying the same type of enumerator allocation.

Below are the relevant differences in IL. A value based enumerator is certainly preferable!

IL_0001:  callvirt   instance class
          [mscorlib]System.Collections.Generic.IEnumerator`1<!0> 
          class [mscorlib]System.Collections.Generic.IEnumerable`1<!!T>::GetEnumerator()

vs

IL_0001:  callvirt   instance valuetype
          [mscorlib]System.Collections.Generic.List`1/Enumerator<!0>
          class [mscorlib]System.Collections.Generic.List`1<int32>::GetEnumerator()

Conclusion

The OP asked how to call ForEach() on an IEnumerable<T>. The original answer clearly shows how it can be done. Sure you can do it, but then again; my answer clearly shows that you shouldn't.

Verified the same behavior when targeting .NET Core 3.1.401 (compiling with Visual Studio 16.7.2).

l33t
  • 18,692
  • 16
  • 103
  • 180
  • 1
    Very clear analysis, not sure if you give as good an account of recommended course of action. Even if it was a link to an article on best practice would be really helpful. I guess you mean don't use linq for this use ````foreach(x in y){ f(x) }```` – Craig.C Sep 11 '20 at 08:49
  • Strange: there is a difference between wether you call getenumerator on a interface declared variable vs interface declared variable which seems to cause garbage. As both would call the same actual implementation. Besides that I think when you are scanning a collection so often your algorithm has a computational complexity that is really bad. So I wander what scenario's this is relevant that cannot be simply improved by writing a proper algorithm. – Wouter Nov 12 '20 at 11:57
  • It's relevant in any case you can think of. Unless your programs are 100% loop free. – l33t Nov 12 '20 at 12:16
  • @SørenBoisen You're free to have an opinion. If you prefer to write inefficient code just because you can, then please do. Our company spent millions of dollars analyzing/refactoring this very exact `ForEach` extension. Once you fully understand its pitfalls, you will simply not allow this junk in your repository. – l33t Mar 10 '21 at 09:41
  • 1
    I believe the word you were looking for is "weakly". – Gregory Shields Nov 16 '21 at 19:30
  • 1
    @GregoryShields I take it you read my answer thoroughly :) – l33t Nov 16 '21 at 22:39
  • @l33t Indeed I did, and an excellent answer it was. :-) – Gregory Shields Nov 28 '21 at 21:04
26

Keep your Side Effects out of my IEnumerable

I'd like to do the equivalent of the following in LINQ, but I can't figure out how:

As others have pointed out here and abroad LINQ and IEnumerable methods are expected to be side-effect free.

Do you really want to "do something" to each item in the IEnumerable? Then foreach is the best choice. People aren't surprised when side-effects happen here.

foreach (var i in items) i.DoStuff();

I bet you don't want a side-effect

However in my experience side-effects are usually not required. More often than not there is a simple LINQ query waiting to be discovered accompanied by a StackOverflow.com answer by either Jon Skeet, Eric Lippert, or Marc Gravell explaining how to do what you want!

Some examples

If you are actually just aggregating (accumulating) some value then you should consider the Aggregate extension method.

items.Aggregate(initial, (acc, x) => ComputeAccumulatedValue(acc, x));

Perhaps you want to create a new IEnumerable from the existing values.

items.Select(x => Transform(x));

Or maybe you want to create a look-up table:

items.ToLookup(x, x => GetTheKey(x))

The list (pun not entirely intended) of possibilities goes on and on.

Community
  • 1
  • 1
cdiggins
  • 17,602
  • 7
  • 105
  • 102
25

I took Fredrik's method and modified the return type.

This way, the method supports deferred execution like other LINQ methods.

EDIT: If this wasn't clear, any usage of this method must end with ToList() or any other way to force the method to work on the complete enumerable. Otherwise, the action would not be performed!

public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
    foreach (T item in enumeration)
    {
        action(item);
        yield return item;
    }
}

And here's the test to help see it:

[Test]
public void TestDefferedExecutionOfIEnumerableForEach()
{
    IEnumerable<char> enumerable = new[] {'a', 'b', 'c'};

    var sb = new StringBuilder();

    enumerable
        .ForEach(c => sb.Append("1"))
        .ForEach(c => sb.Append("2"))
        .ToList();

    Assert.That(sb.ToString(), Is.EqualTo("121212"));
}

If you remove the ToList() in the end, you will see the test failing since the StringBuilder contains an empty string. This is because no method forced the ForEach to enumerate.

Dor Rotman
  • 1,511
  • 1
  • 15
  • 27
  • Your alternate implementation of `ForEach` is interesting, however it does not match the behavior of `List.ForEach`, the signature of which is `public void ForEach(Action action)`. It also does not match the behavior of the `Observable.ForEach` extension to `IObservable`, the signature of which is `public static void ForEach(this IObservable source, Action onNext)`. FWIW, the `ForEach` equivalent on Scala collections, even those which are lazy, also have return type which is equivalent to void in C#. – drstevens Nov 30 '11 at 21:10
  • 1
    This is the best answer: deferred execution + fluent api. – Alexander Danilov Jul 10 '15 at 21:50
  • 4
    This works exactly the same as calling `Select` with `ToList`. The purpose of `ForEach` is to not having to call `ToList`. It should execute immediately. – t3chb0t Jul 30 '16 at 11:59
  • 3
    What would be the benefit of having this "ForEach", whose execution is deferred, vs. one that executes immediately? Deferring (which is inconvenient in how ForEach will be used) doesn't ameliorate the fact that ForEach only performs useful work if the Action has side-effects [the usual complaint that is made against such a Linq operator]. So, how *does* this change help? In addition, the added "ToList()" to force it to execute, serves no useful purpose. Its an accident waiting to happen. The point of "ForEach" is its side-effects. If you WANT a returned enumeration, SELECT makes more sense. – ToolmakerSteve Mar 03 '17 at 04:13
18

If you want to act as the enumeration rolls you should yield each item.

public static class EnumerableExtensions
{
    public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
    {
        foreach (var item in enumeration)
        {
            action(item);
            yield return item;
        }
    }
}
Legends
  • 21,202
  • 16
  • 97
  • 123
regisbsb
  • 3,664
  • 2
  • 35
  • 41
11

There is an experimental release by Microsoft of Interactive Extensions to LINQ (also on NuGet, see RxTeams's profile for more links). The Channel 9 video explains it well.

Its docs are only provided in XML format. I have run this documentation in Sandcastle to allow it to be in a more readable format. Unzip the docs archive and look for index.html.

Among many other goodies, it provides the expected ForEach implementation. It allows you to write code like this:

int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8 };

numbers.ForEach(x => Console.WriteLine(x*x));
Athari
  • 33,702
  • 16
  • 105
  • 146
John Wigger
  • 904
  • 8
  • 10
8

According to PLINQ (available since .Net 4.0), you can do an

IEnumerable<T>.AsParallel().ForAll() 

to do a parallel foreach loop on an IEnumerable.

Wolf5
  • 16,600
  • 12
  • 59
  • 58
  • as long as your action is threadsafe, all is good. but what will happen if you have a non-threadsafe action to perform? it can cause quite a mayhem... – shirbr510 Mar 16 '16 at 13:52
  • 2
    True. It is not thread safe, different threads will be used from some thread pool... And I need to revise my answer. There is no ForEach() when I try it now.. Must have been my code containing an Extension with ForEach when I pondered with this. – Wolf5 Mar 17 '16 at 14:07
7

The purpose of ForEach is to cause side effects. IEnumerable is for lazy enumeration of a set.

This conceptual difference is quite visible when you consider it.

SomeEnumerable.ForEach(item=>DataStore.Synchronize(item));

This wont execute until you do a "count" or a "ToList()" or something on it. It clearly is not what is expressed.

You should use the IEnumerable extensions for setting up chains of iteration, definining content by their respective sources and conditions. Expression Trees are powerful and efficient, but you should learn to appreciate their nature. And not just for programming around them to save a few characters overriding lazy evaluation.

Tormod
  • 4,551
  • 2
  • 28
  • 50
5

Many people mentioned it, but I had to write it down. Isn't this most clear/most readable?

IEnumerable<Item> items = GetItems();
foreach (var item in items) item.DoStuff();

Short and simple(st).

Nenad
  • 24,809
  • 11
  • 75
  • 93
  • You can drop the whole first line and use GetItems directly in foreach – tymtam Aug 03 '16 at 13:58
  • 3
    Of course. It is written like this for clarity. So that it is clear what `GetItems()` method returns. – Nenad Aug 04 '16 at 08:56
  • 4
    Now when I read my comment I see it seems like I'm telling you something you don't know. I didn't mean that. What I meant is that `foreach (var item in GetItems()) item.DoStuff();` is just a beauty. – tymtam Aug 04 '16 at 23:14
4

As numerous answers already point out, you can easily add such an extension method yourself. However, if you don't want to do that, although I'm not aware of anything like this in the BCL, there's still an option in the System namespace, if you already have a reference to Reactive Extension (and if you don't, you should have):

using System.Reactive.Linq;

items.ToObservable().Subscribe(i => i.DoStuff());

Although the method names are a bit different, the end result is exactly what you're looking for.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
4

ForEach can also be Chained, just put back to the pileline after the action. remain fluent


Employees.ForEach(e=>e.Act_A)
         .ForEach(e=>e.Act_B)
         .ForEach(e=>e.Act_C);

Orders  //just for demo
    .ForEach(o=> o.EmailBuyer() )
    .ForEach(o=> o.ProcessBilling() )
    .ForEach(o=> o.ProcessShipping());


//conditional
Employees
    .ForEach(e=> {  if(e.Salary<1000) e.Raise(0.10);})
    .ForEach(e=> {  if(e.Age   >70  ) e.Retire();});

An Eager version of implementation.

public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enu, Action<T> action)
{
    foreach (T item in enu) action(item);
    return enu; // make action Chainable/Fluent
}

Edit: a Lazy version is using yield return, like this.

public static IEnumerable<T> ForEachLazy<T>(this IEnumerable<T> enu, Action<T> action)
{
    foreach (var item in enu)
    {
        action(item);
        yield return item;
    }
}

The Lazy version NEEDs to be materialized, ToList() for example, otherwise, nothing happens. see below great comments from ToolmakerSteve.

IQueryable<Product> query = Products.Where(...);
query.ForEachLazy(t => t.Price = t.Price + 1.00)
    .ToList(); //without this line, below SubmitChanges() does nothing.
SubmitChanges();

I keep both ForEach() and ForEachLazy() in my library.

Rm558
  • 4,621
  • 3
  • 38
  • 43
  • 2
    Have you tested this? There are several context where this method behaves contra intuitively. Better would be `foreach(T item in enu) {action(item); yield return item;}` – Taemyr Oct 06 '16 at 08:57
  • 3
    This will result in multiple enumerations – regisbsb Oct 21 '16 at 10:40
  • Interesting. Pondering when I would want to do the above, for a sequence of 3 actions, rather than `foreach (T item in enu) { action1(item); action2(item); action3(item); }`? A single, explicit, loop. I guess if it was important to do *all* the action1's BEFORE starting to do action2's. – ToolmakerSteve Mar 03 '17 at 04:52
  • @Rm558 - your approach using "yield return". Pro: only enumerates the original sequence once, so works correctly with a wider range of enumerations. Con: if you forget ".ToArray()" at end, nothing happens. Though the failure will be obvious, not overlooked for long, so not a major cost. Doesn't "feel clean" to me, but is the right tradeoff, if one is going down this road (a ForEach operator). – ToolmakerSteve Mar 03 '17 at 05:05
  • 1
    This code is not safe from transactional point of view. What if it fails in `ProcessShipping()`? You email buyer, charge his credit card, but never send him his stuff? Certainly asking for problems. – zmechanic Apr 13 '17 at 14:10
  • This is equivalent to a `Select`. There's no reason to duplicate that functionality, just return the original value from your iteration function. – jpaugh May 21 '18 at 19:33
4

Now we have the option of...

        ParallelOptions parallelOptions = new ParallelOptions();
        parallelOptions.MaxDegreeOfParallelism = 4;
#if DEBUG
        parallelOptions.MaxDegreeOfParallelism = 1;
#endif
        Parallel.ForEach(bookIdList, parallelOptions, bookID => UpdateStockCount(bookID));

Of course, this opens up a whole new can of threadworms.

ps (Sorry about the fonts, it's what the system decided)

Sklivvz
  • 30,601
  • 24
  • 116
  • 172
Paulustrious
  • 609
  • 1
  • 11
  • 17
3

Inspired by Jon Skeet, I have extended his solution with the following:

Extension Method:

public static void Execute<TSource, TKey>(this IEnumerable<TSource> source, Action<TKey> applyBehavior, Func<TSource, TKey> keySelector)
{
    foreach (var item in source)
    {
        var target = keySelector(item);
        applyBehavior(target);
    }
}

Client:

var jobs = new List<Job>() 
    { 
        new Job { Id = "XAML Developer" }, 
        new Job { Id = "Assassin" }, 
        new Job { Id = "Narco Trafficker" }
    };

jobs.Execute(ApplyFilter, j => j.Id);

. . .

public void ApplyFilter(string filterId)
{
    Debug.WriteLine(filterId);
}
Petter Hesselberg
  • 5,062
  • 2
  • 24
  • 42
Scott Nimrod
  • 11,206
  • 11
  • 54
  • 118
2

This "functional approach" abstraction leaks big time. Nothing on the language level prevents side effects. As long as you can make it call your lambda/delegate for every element in the container - you will get the "ForEach" behavior.

Here for example one way of merging srcDictionary into destDictionary (if key already exists - overwrites)

this is a hack, and should not be used in any production code.

var b = srcDictionary.Select(
                             x=>
                                {
                                  destDictionary[x.Key] = x.Value;
                                  return true;
                                }
                             ).Count();
Zar Shardan
  • 5,675
  • 2
  • 39
  • 37
  • 8
    If you have to add that disclaimer, you probably shouldn't post it. Just my opinion. – Andrew Grothe Oct 29 '12 at 14:10
  • 2
    How the hell is this better than `foreach(var tuple in srcDictionary) { destDictionary[tuple.Key] = tuple.Value; }`? If not in production code where and why should you ever use this? – Mark Sowul Jul 29 '13 at 04:27
  • 3
    This just to show it is possible in principle. It also happens to do what OP asked for, and I clearly indicated it should not be used in production, still curious and has educational value. – Zar Shardan Jul 29 '13 at 13:53
2

MoreLinq has IEnumerable<T>.ForEach and a ton of other useful extensions. It's probably not worth taking the dependency just for ForEach, but there's a lot of useful stuff in there.

https://www.nuget.org/packages/morelinq/

https://github.com/morelinq/MoreLINQ

solublefish
  • 1,681
  • 2
  • 18
  • 24
1

I respectually disagree with the notion that link extension methods should be side-effect free (not only because they aren't, any delegate can perform side effects).

Consider the following:

   public class Element {}

   public Enum ProcessType
   {
      This = 0, That = 1, SomethingElse = 2
   }

   public class Class1
   {
      private Dictionary<ProcessType, Action<Element>> actions = 
         new Dictionary<ProcessType,Action<Element>>();

      public Class1()
      {
         actions.Add( ProcessType.This, DoThis );
         actions.Add( ProcessType.That, DoThat );
         actions.Add( ProcessType.SomethingElse, DoSomethingElse );
      }

      // Element actions:

      // This example defines 3 distict actions
      // that can be applied to individual elements,
      // But for the sake of the argument, make
      // no assumption about how many distict
      // actions there may, and that there could
      // possibly be many more.

      public void DoThis( Element element )
      {
         // Do something to element
      }

      public void DoThat( Element element )
      {
         // Do something to element
      }

      public void DoSomethingElse( Element element )
      {
         // Do something to element
      }

      public void Apply( ProcessType processType, IEnumerable<Element> elements )
      {
         Action<Element> action = null;
         if( ! actions.TryGetValue( processType, out action ) )
            throw new ArgumentException("processType");
         foreach( element in elements ) 
            action(element);
      }
   }

What the example shows is really just a kind of late-binding that allows one invoke one of many possible actions having side-effects on a sequence of elements, without having to write a big switch construct to decode the value that defines the action and translate it into its corresponding method.

  • 9
    There's a difference between whether an extension method CAN have side-effectsand whether it SHOULD have. You're only pointing out that it can have, while there may be very good reasons to propose that they should not have side effects. In functional programming, all functions are side-effect free, and when using functional programming constructs you may want to assume that they are. – Dave Van den Eynde Apr 02 '10 at 13:32
1

To stay fluent one can use such a trick:

GetItems()
    .Select(i => new Action(i.DoStuf)))
    .Aggregate((a, b) => a + b)
    .Invoke();
CSDev
  • 3,177
  • 6
  • 19
  • 37
0

For VB.NET you should use:

listVariable.ForEach(Sub(i) i.Property = "Value")
Israel Margulies
  • 8,656
  • 2
  • 30
  • 26
  • NOTE: This compiles only if you have a `List` or `IList`. For a general `IEnumerable`, write the VB equivalent of [the accepted answer's](http://stackoverflow.com/a/200584/199364) ForEach extension method. – ToolmakerSteve Mar 03 '17 at 04:45
-2

Yet another ForEach Example

public static IList<AddressEntry> MapToDomain(IList<AddressModel> addresses)
{
    var workingAddresses = new List<AddressEntry>();

    addresses.Select(a => a).ToList().ForEach(a => workingAddresses.Add(AddressModelMapper.MapToDomain(a)));

    return workingAddresses;
}
akjoshi
  • 15,374
  • 13
  • 103
  • 121
  • 6
    What a waste of memory. This calls ToList to add to a list. Why doesn't this just return addresses.Select(a => MapToDomain(a))? – Mark Sowul Jul 29 '13 at 04:30