1

For example, i have array of int and i need increase each element by 2. In modern c# with linq and extension methods the obvious solution is:

var array = new[] {1, 2, 3};
array.ForEach(p => p += 2);

But unfortunately, code will not compile, because ForEach is not extension method of IEnumerable, but its a member if List. So i need to use classic foreach loop or cast array to list, but this solutions not so elegant and simple.

Can anybody tell me, why Microsoft design ForEach method as member of List, but not as extension method of IEnumerable?

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
Sergey Shulik
  • 950
  • 1
  • 9
  • 24
  • 3
    http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx – Dennis_E Aug 10 '15 at 09:28
  • Your own sample is a *great* example of why in fact - you're causing horrible side effects, and *it wouldn't work anyway* (you're updating an argument, no the value in the array). LINQ is based on some functional paradigms, and one of the biggies is that you must not cause side-effects - if your code actually worked, that would be exactly what you'd be doing. The proper functional way would be to simply return a new array, of course - exactly what `Select` does. Not to mention that `IEnumerable` is a read-only contract - you're not going to modify it anyway. – Luaan Aug 10 '15 at 09:43
  • @luaan Yes, you are right. Its bad example and bad idea to modify ValueTypes like this :) – Sergey Shulik Aug 10 '15 at 09:45
  • @Luaan - The Ix-Main NuGet package from the Reactive Extensions team provides a `ForEach` extension method for `IEnumerable`. So it would seem that somebody at Microsoft finds value in it. – Jason Boyd Aug 10 '15 at 14:25
  • @JasonBoyd That quite agrees with Eric's point. In any case, there's plenty of things everyone at Microsoft doesn't agree on :) Reactive Extensions' `ForEach` is quite explicitly for side-effects - it's handy when using Rx for scheduling, for example (something like `Observable.Interval(TimeSpan.FromSeconds(1)).Take(5).ForEach(i => Console.WriteLine(i))`). It also stands in contrast to `Subscribe`. It's adding a bit of TPL into Rx in a way. – Luaan Aug 10 '15 at 15:36
  • @Luaan - I want to preface this by saying that my comment was not an endorsement of or an objection to Eric's argument. I simply wanted to point out what you picked up on, which is that 'there's plenty of things everyone at Microsoft doesn't agree on'. I also want to point out that `Ix-Main`, while coming from the Rx team, has little to do with Rx. The `Ix-Main` project contains additional extension methods for `IEnumerable`, including `ForEach`; it is more in the spirit of the now defunct MoreLINQ project (I am pretty sure it is dead). – Jason Boyd Aug 10 '15 at 16:35

0 Answers0