416

Inspired by another question asking about the missing Zip function:

Why is there no ForEach extension method on the IEnumerable interface? Or anywhere? The only class that gets a ForEach method is List<>. Is there a reason why it's missing, maybe performance?

Sergey
  • 1,384
  • 1
  • 24
  • 34
Cameron MacFarland
  • 65,569
  • 20
  • 98
  • 130
  • 2
    Related question here with link to 'official answer' http://stackoverflow.com/questions/858978/lambda-expression-using-foreach-clause – Benjol Jun 04 '09 at 13:06
  • 1
    See also http://stackoverflow.com/questions/200574/linq-equivalent-of-foreach-for-ienumerablet – goodeye Jun 27 '12 at 01:41
  • 1
    I think one very important point is, that a foreach loop is easier to spot. If you use .ForEach(...) it easy to miss this one, when you look through the code. This becomes important, when you have performance issues. Of course .ToList() and .ToArray() have the same issue but they are used a little different. Another reason could be that it's more common in a .ForEach to modify the source list (f.e. removing/adding elements) so it would not be a "pure" query anymore. – Daniel Bişar Oct 31 '14 at 10:12
  • When debugging parallelised code, I often try swapping `Parallel.ForEach` for `Enumerable.ForEach` only to rediscover the latter doesn't exist. C# missed a trick to make things easy here. – Colonel Panic Jun 01 '16 at 10:01
  • "Just rewrite it as a foreach loop, the syntax only differs at the beginning, middle and end." Cheers for that. – Colonel Panic Jun 01 '16 at 10:03
  • 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:31
  • Most of the answers and comments here defending this absence are foolish and ignorant. But since the C# designers have no sense, write your own: `public static void ForEach(this IEnumerable list, Action action) { foreach (T item in list) action(item); } ` ... and here is the one that is analogous to `Select` with an index: `public static void ForEach(this IEnumerable list, Action action) { int i = 0; foreach (T item in list) action(item, i); }` – Jim Balter Feb 27 '17 at 10:40
  • Its probably as hinted by an earlier post, in that foreach is supported as a language keyword in C# and VB.NET (and many others) Most people (myself included) simply write one themselves as needed and appropriate. – chrisb Sep 19 '08 at 11:54
  • The question still doesn't have clear and reasonable answer. – isevcik Nov 21 '18 at 13:37

21 Answers21

208

There is already a foreach statement included in the language that does the job most of the time.

I'd hate to see the following:

list.ForEach( item =>
{
    item.DoSomething();
} );

Instead of:

foreach(Item item in list)
{
     item.DoSomething();
}

The latter is clearer and easier to read in most situations, although maybe a bit longer to type.

However, I must admit I changed my stance on that issue; a ForEach() extension method would indeed be useful in some situations.

Here are the major differences between the statement and the method:

  • Type checking: foreach is done at runtime, ForEach() is at compile time (Big Plus!)
  • The syntax to call a delegate is indeed much simpler: objects.ForEach(DoSomething);
  • ForEach() could be chained: although evilness/usefulness of such a feature is open to discussion.

Those are all great points made by many people here and I can see why people are missing the function. I wouldn't mind Microsoft adding a standard ForEach method in the next framework iteration.

Sergey
  • 1,384
  • 1
  • 24
  • 34
Coincoin
  • 25,460
  • 7
  • 49
  • 73
  • Hmm, good point. The only thing I can think of that counters this is the fact that List<> also has a ForEach method. Unfortunately I can't think of an example where having a ForEach would be useful syntacticly. – Cameron MacFarland Sep 19 '08 at 12:07
  • 1
    leppie: You call the delegate in the foreach :) – Coincoin Sep 19 '08 at 12:29
  • 1
    If DoSomething was a local/static method, then it would look much cleaner using the ForEach method: list.ForEach(DoSomething); – Nathan Baulch Sep 19 '08 at 13:56
  • 45
    The discussion here gives the answer: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2386791&SiteID=1 Basically the decision was made to keep the extension methods functionally "pure". A ForEach would encourage side-effects when using the extension methods, which was not the intent. – mancaus Oct 12 '08 at 10:47
  • But, Mancaus, Enumerable already has extension method with side effect . Such as Count and Reverse. – Morgan Cheng Jan 05 '09 at 05:21
  • 1
    sometimes it's clearer with the extension method, don't try to pretend using statement lambda synthax: list.ForEach( item => item.DoSomething()); – Olmo Jan 24 '09 at 18:59
  • 18
    'foreach' may seem clearer if you have a C background, but internal iteration more clearly states your intent. That means you could do things like 'sequence.AsParallel().ForEach(...)'. – Jay Bazuzi Feb 02 '09 at 18:32
  • 6
    @Morgan, What side effects does Count and Reverse have? As far as I know, they do nothing to the original enumeration. Same with OrderBy and its relatives. The original whatever-it-was is left untouched. – Svish Aug 27 '09 at 13:50
  • 10
    I'm not sure your point about type checking is correct. `foreach` is type checked at compile time if the enumerable is parameterised. It only lacks compile time type checking for non-generic collections, as would a hypothetical `ForEach` extension method. – Richard Poole Jan 11 '11 at 02:19
  • 3
    lol, I did, but I decided because it starts off with the anti-each rant, then it is still taking that position. – Mark Rogers Jun 21 '11 at 20:30
  • 55
    Extension method would be really useful in chain LINQ with dot notation, like: ``col.Where(...).OrderBy(...).ForEach(...)``. Much simpler syntax, no screen pollution with either redundant local variables or long brackets in foreach(). – Jacek Gorgoń Feb 28 '12 at 10:19
  • 3
    Old question, but your last bullet point is incorrect. `ForEach` cannot be chained because its return type is `void`. A custom implementation could be, of course. – Kenneth K. May 05 '15 at 19:55
  • 1
    A .ForEach() method at the end of the chain looks much cleaner when all you want is to operate one time at the result. Besides, a ForEach can provide an overload with the index, so we don't have to duplicate the usual workaround every time. – Thomas Eyde Sep 04 '15 at 07:59
  • 4
    Using existing language feature as an argument is kind of weak, isn't it? Then we would never get beyond C# 1. – Thomas Eyde Sep 04 '15 at 08:01
  • 4
    This doesn't answer **why** there's no `ForEach` method on `IEnumerable<>`. – IEatBagels Sep 17 '15 at 13:19
  • Here is it. Vote it up! https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/2536020-add-enumerable-foreach-extension-method – Moslem Ben Dhaou Oct 27 '15 at 12:46
  • I would name it `Apply` and let it return an `IEnumerable`, so that it could appear at any place in a chain. `public static IEnumerable Apply(this IEnumerable list, Action action) { foreach (T item in list) { action(item); } return list; }`. – Olivier Jacot-Descombes Oct 11 '16 at 17:17
  • @OlivierJacot-Descombes Your Apply is misleading, pointlessly inefficient, and doesn't work if the enumerable has side effects like reading from a stream. Instead of `collection.Apply(x => f(x)).Apply(x => g(x))`, do `collection.Foreach(x => { f(x); g(x); })` – Jim Balter Feb 27 '17 at 10:18
  • 31
    "I'd hate to see the following" -- The question wasn't about your personal preferences, and you made the code more hateful by adding extraneous linefeeds and an extraneous pair of braces. Not so hateful is `list.ForEach(item => item.DoSomething())`. And who says it's a list? The obvious use case is at the end of a chain; with the foreach statement, you would have to put the whole chain after `in`, and the operation to performed inside the block, which is far less natural or consistent. – Jim Balter Feb 27 '17 at 10:28
  • 2
    I think it would be great to be able to do: `items.Where(item => [test on item]).ForEach([do stuff])` instead of `items.Where(item => [test on item]).ToList().ForEach([do stuff])`. The "ToList" doesn't seem to add anything, and makes it slightly less readable (when you have several links, nested for-loops are definitely not more readable, in my opinion). – Svend Hansen Mar 15 '17 at 11:22
  • 2
    The worst answer I even seen. Your preferences is not a reason – Herrgott Feb 15 '19 at 09:40
  • 1
    "I would hate to see" yet `enumerable.ToList().ForEach(i => ... )` is so much worse. – Captain Prinny Nov 20 '19 at 17:31
  • I don't see **nothing bad** in `sequence.ForEach(x => ...)`. – gsscoder Jan 13 '20 at 12:52
  • ienumerable?.ForEeach(x => ) is much better than null pointer exceptions on foreach(var t in ienumerable){} – Chris DaMour May 27 '20 at 21:56
  • I'd hate to see the first example too, because a method group would be better than either: `list.ForEach(DoSomething);` – defines Mar 04 '21 at 19:56
80

ForEach method was added before LINQ. If you add ForEach extension, it will never be called for List instances because of extension methods constraints. I think the reason it was not added is to not interference with existing one.

However, if you really miss this little nice function, you can roll out your own version

public static void ForEach<T>(
    this IEnumerable<T> source,
    Action<T> action)
{
    foreach (T element in source) 
        action(element);
}
aku
  • 115,356
  • 31
  • 164
  • 200
  • 11
    The extension methods allow for this. If there is already an instance implementation of a given method name then that method is used instead of the extension method. So you can implement an extension method ForEach and not have it collide with the List<>.ForEach method. – Cameron MacFarland Sep 19 '08 at 11:57
  • 3
    Cameron, believe me I know how extension methods work :) List inherits IEnumerable so it will be non-obvious thing. – aku Sep 19 '08 at 12:02
  • 9
    From the Extension Methods Programming Guide (http://msdn.microsoft.com/en-us/library/bb383977.aspx): An extension method with the same name and signature as an interface or class method will never be called. Seems pretty obvious to me. – Cameron MacFarland Sep 19 '08 at 12:11
  • 3
    Am I talking something different? I think it's no good when many classes have ForEach method but some of them may work differently. – aku Sep 19 '08 at 12:14
  • Ah sorry. When you said "interference with existing one" I thought you were suggesting that the extension method would override the local version. Re-reading made me realise we're talking about the same thing. :) – Cameron MacFarland Sep 19 '08 at 12:18
  • 5
    One interesting thing to note about List<>.ForEach and Array.ForEach is that they are not actually using the foreach construct internally. They both use a plain for loop. Maybe it's a performance thing (http://diditwith.net/2006/10/05/PerformanceOfForeachVsListForEach.aspx). But given that, Array and List both implement ForEach methods, it's surprising that they didn't at least implement an extension method for IList<>, if not for IEnumerable<> too. – Matt Dotson Mar 22 '12 at 23:35
  • "it will never be called for List instances because of extension methods constraints" -- irrelevant as long as they have the same semantics. " I think it's no good when many classes have ForEach method but some of them may work differently" -- but they **don't** act differently in this case. "I think" -- not a valid form of answer. Responses to "why" questions that are guesses should be entered as comments, not answers. As it so happens, your guess is wrong. Still, credit for providing an implementation. – Jim Balter Feb 27 '17 at 11:11
  • 1
    @MattDotson The compiler special-cases the `foreach` statement for arrays to do an indexed loop, so it will be at least as fast as `ForEach()`. Ultimately, the performance will depend on what code the JIT produces. – Jim Balter Feb 27 '17 at 11:18
  • Not worth its own answer, just sharing a library that has (something like) this and many other useful extensions https://github.com/morelinq/MoreLINQ – defines Mar 05 '21 at 19:16
55

You could write this extension method:

// Possibly call this "Do"
IEnumerable<T> Apply<T> (this IEnumerable<T> source, Action<T> action)
{
    foreach (var e in source)
    {
        action(e);
        yield return e;
    }
}

Pros

Allows chaining:

MySequence
    .Apply(...)
    .Apply(...)
    .Apply(...);

Cons

It won't actually do anything until you do something to force iteration. For that reason, it shouldn't be called .ForEach(). You could write .ToList() at the end, or you could write this extension method, too:

// possibly call this "Realize"
IEnumerable<T> Done<T> (this IEnumerable<T> source)
{
    foreach (var e in source)
    {
        // do nothing
        ;
    }

    return source;
}

This may be too significant a departure from the shipping C# libraries; readers who are not familiar with your extension methods won't know what to make of your code.

Jay Bazuzi
  • 41,333
  • 12
  • 104
  • 161
  • 1
    Your first function could be used w/out the 'realize' method if written like: `{foreach (var e in source) {action(e);} return source;}` – jjnguy Dec 09 '10 at 22:15
  • 4
    Couldn't you just use Select instead of your Apply method? It seems to me that applying an action to each element and yielding it is exactly what Select does. E.g. `numbers.Select(n => n*2);` – rasmusvhansen Feb 22 '13 at 08:44
  • 1
    I think Apply is more readable than using Select for this purpose. When reading a Select statement, I read it as "get something from inside" where as Apply is "do some work to". – Dr Rob Lang Oct 22 '13 at 08:46
  • @jinguy The problem with that is enumerables with side effects (reading a file) won't work properly. – NetMage Jan 18 '18 at 23:17
  • 2
    @rasmusvhansen Actually, `Select()` says apply a function to each element and return the value of the function where `Apply()` says apply an `Action` to each element and return the __original__ element. – NetMage Jan 18 '18 at 23:18
  • 2
    This is equivalent to `Select(e => { action(e); return e; })` – Jim Balter Oct 10 '18 at 06:34
39

The discussion here gives the answer:

Actually, the specific discussion I witnessed did in fact hinge over functional purity. In an expression, there are frequently assumptions made about not having side-effects. Having ForEach is specifically inviting side-effects rather than just putting up with them. -- Keith Farmer (Partner)

Basically the decision was made to keep the extension methods functionally "pure". A ForEach would encourage side-effects when using the Enumerable extension methods, which was not the intent.

sashoalm
  • 63,456
  • 96
  • 348
  • 677
mancaus
  • 2,873
  • 1
  • 17
  • 16
  • 7
    See also http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx . Ddoing so violates the functional programming principles that all the other sequence operators are based upon. Clearly the sole purpose of a call to this method is to cause side effects – Michael Freidgeim Jul 07 '12 at 23:16
  • 11
    That reasoning is completely bogus. The *use case* is that side effects are needed ... without ForEach, you have to write a foreach loop. The existence of ForEach does not encourage side effects and its absence does not reduce them. – Jim Balter Oct 10 '18 at 06:06
  • Given how simple it is to write the extension method, there's literally no reason that it's not language standard. – Captain Prinny Nov 20 '19 at 17:33
  • Archive for @MichaelFreidgeim's now dead link: https://web.archive.org/web/20151205151706/http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx – Vapid Linus Mar 29 '21 at 09:35
19

While I agree that it's better to use the built-in foreach construct in most cases, I find the use of this variation on the ForEach<> extension to be a little nicer than having to manage the index in a regular foreach myself:

public static int ForEach<T>(this IEnumerable<T> list, Action<int, T> action)
{
    if (action == null) throw new ArgumentNullException("action");

    var index = 0;

    foreach (var elem in list)
        action(index++, elem);

    return index;
}
Example
var people = new[] { "Moe", "Curly", "Larry" };
people.ForEach((i, p) => Console.WriteLine("Person #{0} is {1}", i, p));

Would give you:

Person #0 is Moe
Person #1 is Curly
Person #2 is Larry
Chris Zwiryk
  • 1,281
  • 9
  • 9
  • Great extension, but could you add some documentation? What is the intended use of the returned value? Why is index var rather than specifically an int? Sample usage? – Mark T Mar 19 '09 at 14:26
  • Mark: The return value is the number of elements in the list. Index *is* specifically typed as an int, thanks to implicit typing. – Chris Zwiryk Mar 19 '09 at 20:37
  • @Chris, based on your code above, the return value is the zero-based index of the last value in the list, not the number of elements in the list. – Eric Smith May 16 '09 at 11:07
  • @Chris, no it isn't: index is incremented after the value has been taken (postfix increment), so after the first element has been processed, index will be 1 and so on. So the return value really is the element count. – MartinStettner Aug 27 '09 at 13:56
  • @MartinStettner, no what? This method is supposed to return the element count. – Chris Zwiryk Aug 27 '09 at 15:14
  • 1
    @MartinStettner the comment from Eric Smith on 5/16 was from an earlier version. He corrected the code on 5/18 to return the correct value. – Michael Blackburn Mar 21 '14 at 15:32
17

One workaround is to write .ToList().ForEach(x => ...).

pros

Easy to understand - reader only needs to know what ships with C#, not any additional extension methods.

Syntactic noise is very mild (only adds a little extranious code).

Doesn't usually cost extra memory, since a native .ForEach() would have to realize the whole collection, anyway.

cons

Order of operations isn't ideal. I'd rather realize one element, then act on it, then repeat. This code realizes all elements first, then acts on them each in sequence.

If realizing the list throws an exception, you never get to act on a single element.

If the enumeration is infinite (like the natural numbers), you're out of luck.

Jay Bazuzi
  • 41,333
  • 12
  • 104
  • 161
  • 1
    a) This is not even remotely an answer to the question. b) This response would be clearer if it mentioned up front that, while there is no `Enumerable.ForEach` method, there is a `List.ForEach` method. c) "Doesn't usually cost extra memory, since a native .ForEach() would have to realize the whole collection, anyway." -- complete and utter nonsense. Here is the implementation of Enumerable.ForEach that C# would provide if it did: `public static void ForEach(this IEnumerable list, Action action) { foreach (T item in list) action(item); }` – Jim Balter Feb 27 '17 at 11:31
15

I've always wondered that myself, that is why that I always carry this with me:

public static void ForEach<T>(this IEnumerable<T> col, Action<T> action)
{
    if (action == null)
    {
        throw new ArgumentNullException("action");
    }
    foreach (var item in col)
    {
        action(item);
    }
}

Nice little extension method.

Alexandr Nikitin
  • 6,740
  • 1
  • 30
  • 40
Aaron Powell
  • 24,268
  • 14
  • 93
  • 147
  • 2
    col could be null... you could check that as well. – Amy B Sep 19 '08 at 12:24
  • Yeah I do check in my library, I just missed it when doing it quickly there. – Aaron Powell Dec 29 '08 at 22:23
  • I find it interesting that everyone checks the action parameter for null, but never the source/col parameter. – Cameron MacFarland Mar 21 '10 at 02:46
  • 2
    I find it interesting that everyone checks parameters for null, when not checking results in an exception as well... – oɔɯǝɹ Jun 10 '13 at 18:05
  • Not at all. A Null Ref exception wouldn't tell you the name of the parameter that was at fault. And you might also check in the loop so you could throw a specific Null Ref saying col[index#] was null for the same reason – Roger Willcocks Jul 21 '15 at 22:07
  • @Roger Willcocks: That would be bad, assuming a certain intention for the extension method. `null` could be a valid element of the enumerable which the action can handle: Imagine the enumerable is a list of string and the action is a trim - it could decide to trim null to an empty string and everything is fine, you definitely don't want an exception in that case. – Christoph Feb 22 '21 at 14:20
  • Sorry my example was terrible (that would only work with a `Select`). – Christoph Feb 22 '21 at 14:35
  • @Christoph NP. I was just going to say that the "Action" is required because it's "what do you want to do with each item", and "nothing" doesn't usually make sense. And your action can choose to report that specific NullRef if you want, because it's yours. – Roger Willcocks Feb 23 '21 at 22:34
8

So there has been a lot of comments about the fact that a ForEach extension method isn't appropriate because it doesn't return a value like the LINQ extension methods. While this is a factual statement, it isn't entirely true.

The LINQ extension methods do all return a value so they can be chained together:

collection.Where(i => i.Name = "hello").Select(i => i.FullName);

However, just because LINQ is implemented using extension methods does not mean that extension methods must be used in the same way and return a value. Writing an extension method to expose common functionality that does not return a value is a perfectly valid use.

The specific arguement about ForEach is that, based on the constraints on extension methods (namely that an extension method will never override an inherited method with the same signature), there may be a situation where the custom extension method is available on all classes that impelement IEnumerable<T> except List<T>. This can cause confusion when the methods start to behave differently depending on whether or not the extension method or the inherit method is being called.

Scott Dorman
  • 40,345
  • 11
  • 74
  • 107
7

You could use the (chainable, but lazily evaluated) Select, first doing your operation, and then returning identity (or something else if you prefer)

IEnumerable<string> people = new List<string>(){"alica", "bob", "john", "pete"};
people.Select(p => { Console.WriteLine(p); return p; });

You will need to make sure it is still evaluated, either with Count() (the cheapest operation to enumerate afaik) or another operation you needed anyway.

I would love to see it brought in to the standard library though:

static IEnumerable<T> WithLazySideEffect(this IEnumerable<T> src, Action<T> action) {
  return src.Select(i => { action(i); return i; } );
}

The above code then becomes people.WithLazySideEffect(p => Console.WriteLine(p)) which is effectively equivalent to foreach, but lazy and chainable.

Jim Balter
  • 15,014
  • 3
  • 38
  • 62
Martijn
  • 11,183
  • 10
  • 46
  • 92
  • Fantastic, it never clicked that a returned select would work like this. A nice use of the method syntax, as I don't think you could do this with the expression syntax (hence I've not thought of it like this before). – Alex KeySmith Feb 13 '14 at 17:07
  • @AlexKeySmith You could do it with expression syntax if C# had a sequence operator, like its forebear. But the whole point of ForEach is that it takes an action with void type, and you can't use void types in expressions in C#. – Jim Balter Oct 10 '18 at 06:18
  • imho, now the `Select` doesn't do anymore what it's supposed to do. it's definitely a solution for what the OP asks - but on topic readability: nobody would expect that the select does execute a function. – Matthias Burger Sep 25 '19 at 13:32
  • @MatthiasBurger If `Select` doesn't do what it's supposed to do that's a problem with the implementation of `Select`, not with the code that calls `Select`, which has no influence over what `Select` does. – Martijn Oct 07 '19 at 09:34
6

Note that the MoreLINQ NuGet provides the ForEach extension method you're looking for (as well as a Pipe method which executes the delegate and yields its result). See:

Dave Clausen
  • 1,237
  • 1
  • 12
  • 22
4

@Coincoin

The real power of the foreach extension method involves reusability of the Action<> without adding unnecessary methods to your code. Say that you have 10 lists and you want to perform the same logic on them, and a corresponding function doesn't fit into your class and is not reused. Instead of having ten for loops, or a generic function that is obviously a helper that doesn't belong, you can keep all of your logic in one place (the Action<>. So, dozens of lines get replaced with

Action<blah,blah> f = { foo };

List1.ForEach(p => f(p))
List2.ForEach(p => f(p))

etc...

The logic is in one place and you haven't polluted your class.

spoulson
  • 20,523
  • 14
  • 72
  • 101
3

Most of the LINQ extension methods return results. ForEach does not fit into this pattern as it returns nothing.

leppie
  • 109,129
  • 16
  • 185
  • 292
  • 2
    ForEach uses Action, which is another form of delegate – Aaron Powell Sep 19 '08 at 11:59
  • 2
    Except leppie's right, all the Enumerable extension methods return a value, so ForEach doesn't fit the pattern. Delegates doesn't come into this. – Cameron MacFarland Sep 19 '08 at 12:02
  • Just that an extension method doesn't have to return a result, it serves the purpose of adding a way to call a frequently used operation – Aaron Powell Sep 19 '08 at 12:39
  • 1
    Indeed, Slace. So what if it doesn't return a value? – TraumaPony Sep 20 '08 at 09:26
  • In functional languages, 'void' generally doesn't exist, so an empty 'unit' is returned. A ForEach method could allow for continuations or some such... at least, that's the way I see it. –  Feb 01 '09 at 16:02
  • it could return identity, which would fix that problem. – Martijn Feb 21 '13 at 12:51
  • @Martijn then you'd run into multiple enumeration issues. – McKay Aug 02 '13 at 13:31
  • @McKay : how so? You're returning a new enumeration anyway, that can be traversed again, even if the original enumeration could only be traversed once. – Martijn Aug 04 '13 at 14:11
  • @Martijn returning identity would mean that the enumeration is run through both in the `foreach` in the method, and then also returned, which could then be `.ToList()` ed. Both the `foreach` and the `.ToList()` enumerate through the collection. No other Linq methods, via chaining or otherwise, multiply enumerate through an enumeration. `yield return` in the `foreach` in the extension method would be much more performant. But then wouldn't actually foreach until enumerated. – McKay Aug 06 '13 at 13:22
  • 1
    @Martijn i.e. `public IEnumerable Foreach(this IEnumerable items, Action action) { /* error check */ foreach (var item in items) { action(item); yield return item; } }` – McKay Aug 06 '13 at 13:27
  • @user29439 In functional languages, ForEach isn't needed because you can pass unit functions to `map` (which Microsoft idiotically calls `Select`). – Jim Balter Feb 27 '17 at 10:45
  • "Except leppie's right, all the Enumerable extension methods return a value, so ForEach doesn't fit the pattern. Delegates doesn't come into this." -- Whoosh! Of course they do ... C# special-cases `void`; it can't be the value of a type parameter. That's why Action is needed in addition to Func. If `void` could be a type parameter, then void functions could be passed to `Select` (called `map` in non-brain-damaged languages) and there would be no need for `ForEach`. – Jim Balter Feb 27 '17 at 10:50
  • @McKay "But then wouldn't actually foreach until enumerated" -- which makes it pointless. You would need to make it the collection of a `foreach` statement, or do `...ForEach(x => f(x)).ReallyForEach(x => {})` where `ReallyForEach` doesn't have the `yield`. The fact is that ForEach() should end a chain just like `Count()`, `Min()` and `Max()` end the chain ... none return an IEnumerable. – Jim Balter Feb 27 '17 at 10:57
  • @McKay P.S. You can already do your version of ForEach with `Select(x => { f(x); return x; })` – Jim Balter Feb 27 '17 at 11:03
  • @JimBalter Exactly my point (From 3 years ago). Having such a foreach doesn't make sense. – McKay Feb 27 '17 at 20:13
  • @McKay What I wrote is not "exactly [your] point". Again: "The fact is that ForEach() should end a chain just like Count(), Min() and Max() end the chain ... none return an IEnumerable." A perfectly sensible implementation is `public static void ForEach(this IEnumerable list, Action action) { foreach (T item in list) action(item); }` -- it returns `void`, as it must, not `IEnumerable`, which is indeed bad. – Jim Balter Oct 10 '18 at 06:59
  • @JimBalter There's also no need for your new implementation. Sure, you could argue it "follows the rules", but it doesn't buy you anything besides a new functional overhead. – McKay Oct 13 '18 at 01:19
  • @McKay There's no *need* for anything … we could write in machine code, or forego writing programs at all. But the issue here is a ForEach function, and it won't exist if there isn't an implementation. And there's value in it, as many other comments here have pointed out. I never said anything about it being needed; that's a strawman, and I demand a certain level of good faith engagement from my correspondents, so I will not engage further. – Jim Balter Oct 13 '18 at 05:11
  • @JimBalter Sorry, I didn't mean "need". I just don't see how it adds really any value https://blogs.msdn.microsoft.com/ericlippert/2009/05/18/foreach-vs-foreach/ – McKay Oct 14 '18 at 06:28
3

If you have F# (which will be in the next version of .NET), you can use

Seq.iter doSomething myIEnumerable

vzwick
  • 10,424
  • 5
  • 39
  • 60
TraumaPony
  • 10,573
  • 12
  • 52
  • 72
  • 9
    So Microsoft chose not to provide a ForEach method for an IEnumerable in C# and VB, because it would not be purely functional; yet they DID provide it (name iter) in their more functional language, F#. Their logic alludes me. – Scott Hutchinson Aug 16 '17 at 17:38
3

Partially it's because the language designers disagree with it from a philosophical perspective.

  • Not having (and testing...) a feature is less work than having a feature.
  • It's not really shorter (there's some passing function cases where it is, but that wouldn't be the primary use).
  • It's purpose is to have side effects, which isn't what linq is about.
  • Why have another way to do the same thing as a feature we've already got? (foreach keyword)

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

McKay
  • 11,801
  • 5
  • 46
  • 74
2

Is it me or is the List<T>.Foreach pretty much been made obsolete by Linq. Originally there was

foreach(X x in Y) 

where Y simply had to be IEnumerable (Pre 2.0), and implement a GetEnumerator(). If you look at the MSIL generated you can see that it is exactly the same as

IEnumerator<int> enumerator = list.GetEnumerator();
while (enumerator.MoveNext())
{
    int i = enumerator.Current;

    Console.WriteLine(i);
}

(See http://alski.net/post/0a-for-foreach-forFirst-forLast0a-0a-.aspx for the MSIL)

Then in DotNet2.0 Generics came along and the List. Foreach has always felt to me to be an implementation of the Vistor pattern, (see Design Patterns by Gamma, Helm, Johnson, Vlissides).

Now of course in 3.5 we can instead use a Lambda to the same effect, for an example try http://dotnet-developments.blogs.techtarget.com/2008/09/02/iterators-lambda-and-linq-oh-my/

davidsleeps
  • 8,999
  • 11
  • 57
  • 73
user18784
  • 21
  • 1
  • 1
    I believe the generated code for "foreach" should have a try-finally block. Because IEnumerator of T inherits from interface IDisposable. So, in the generated finally block, the IEnumerator of T instance should Disposed. – Morgan Cheng Oct 24 '08 at 05:16
2

You can use select when you want to return something. If you don't, you can use ToList first, because you probably don't want to modify anything in the collection.

Paco
  • 8,184
  • 3
  • 28
  • 41
2

In 3.5, all the extension methods added to IEnumerable are there for LINQ support (notice that they are defined in the System.Linq.Enumerable class). In this post, I explain why foreach doesn't belong in LINQ: Existing LINQ extension method similar to Parallel.For?

Community
  • 1
  • 1
Neil
  • 6,747
  • 4
  • 40
  • 42
2

I would like to expand on Aku's answer.

If you want to call a method for the sole purpose of it's side-effect without iterating the whole enumerable first you can use this:

private static IEnumerable<T> ForEach<T>(IEnumerable<T> xs, Action<T> f) {
    foreach (var x in xs) {
        f(x); yield return x;
    }
}
Community
  • 1
  • 1
fredefox
  • 671
  • 3
  • 11
2

I wrote a blog post about it: http://blogs.msdn.com/kirillosenkov/archive/2009/01/31/foreach.aspx

You can vote here if you'd like to see this method in .NET 4.0: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=279093

Kirill Osenkov
  • 8,168
  • 2
  • 30
  • 35
  • was this ever implemented? I imagine not, but is there any other URL that replaces that ticket? MS connect has been discontinued – knocte Apr 06 '20 at 07:58
  • This wasn't implemented. Consider filing a new issue on https://github.com/dotnet/runtime/issues – Kirill Osenkov Apr 25 '20 at 03:25
0

No one has yet pointed out that ForEach<T> results in compile time type checking where the foreach keyword is runtime checked.

Having done some refactoring where both methods were used in the code, I favor .ForEach, as I had to hunt down test failures / runtime failures to find the foreach problems.

Squirrel
  • 1,275
  • 2
  • 16
  • 25
  • 5
    Is this really the case? I fail to see how `foreach` has any less compile time checking. Sure, if your collection is a non-generic IEnumerable, the loop variable will be an `object`, but the same would be true for a hypothetical `ForEach` extension method. – Richard Poole Jan 11 '11 at 02:25
  • 1
    This is mentioned in the accepted answer. However, it is simply wrong (and Richard Poole above is correct). – Jim Balter Feb 27 '17 at 11:38
0

My version an extension method which would allow you to use ForEach on IEnumerable of T

public static class EnumerableExtension
{
        public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
    {
        source.All(x =>
        {
            action.Invoke(x);
            return true;
        });
    }
}
Liran Barniv
  • 1,120
  • 8
  • 7