Search code examples
c#loopsforeachextension-methods

Difference between "foreach" and extension method: ForEach


Could anyone point out the differences between C# statements and their alike extension methods? e.g: foreach vs. .ForEach(the extension method).

If there are any difference, what are they? Security wise? Performance wise? Which one is better to use? Which one is safer? etc.

And if there are no differences, then why bother writing them?

I've been thinking and searching a bit about this question if mine and didn't find my answer.


Solution

  • It depends on the implementation of the extension method you use. Internally, there's really nothing special about most's version of .ForEach.

    There would be minimal/negligable time to load the extension method at app load and compile time. There "May" be minimal overhead to convert the .ForEach syntax into the underlying foreach as it's technically only a wrapper. It could potentially cause security issues, but only because it can create closure sitiuations where your objects may not be collected at the time expected (eg: held in scope longer). Ultimately, there's very, very little difference, and it comes down to taste. Unless of course, you're trying to shave off every millisecond, and in that case, using the native body is the best way to go.

    I would like to mention that the .ForEach strikes against the premise of using lambda statements being purely functional, that is, it breaks the "functional" style and introduces the possibility of side-effects. Using a foreach body makes the code more readable, and explicit.

    Please see: Why there is no ForEach extension method on IEnumerable?

    It's a trade off. The extension method is certainly more concise, and it provides compile time checking. The extension method also can introduce difficulty of readability, difficulty of maintainability, and side-effects.

    Taken from here

    The second reason is that doing so 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 foo)=>{ statement involving foo; });

    which uses almost exactly the same characters in slightly different order. And yet the second version is harder to understand, harder to debug, and introduces closure semantics, thereby potentially changing object lifetimes in subtle ways.