why ForEach Linq Extension on List rather than on IEnumerable
What it comes down to is mutating state using LINQ should be avoided and not encouraged, LINQ's focus is on querying and transforming data, but not in place mutation - you lose many of the benefits of LINQs functional approach (i.e. no side effects, same input produces same output) if you do mutate state.
There is no benefit of Linq offering a ForEach()
extension method over a normal foreach
loop other than that it would aid you in mutating state - hence its not implemented (that's at least my take on it, take it with a grain of salt).
List<T>.ForEach()
isn't an extension method. It's just a method on List<T>
.
One of the main reasons that it isn't available in LINQ (i.e., Enumerable
) is that LINQ queries are supposed to be free of side-effects (so you can, e.g., execute a query multiple times and get the same results without changing them), which makes them very composable. All the LINQ operations that accept delegates are for Func
; none of them accept an Action
delegate.
This was a bug I had posted at Microsoft Connect Website, Microsoft already fixed it in upcoming .NET Edition as mentioned here in the following link.
List.ForEach allows enumeration over modified version of List
This probably isnt directly related to answer but its pretty funny of what I have just found out.
ForEach, delete (works)
List<int> list = new List<int>(){ 1, 2, 3, 4, 5, 6};
list.ForEach(x => {
Console.WriteLine(x);
list.Remove(x);
});
foreach, delete (crashes)
// throws exception
foreach (var x in list)
{
Console.WriteLine(x);
list.Remove(x);
}
ForEach, insert (...)
// goes in infinite loop...
list.ForEach(x => {
list.Add(1);
});
foreach, insert (crashes)
// throws exception
foreach (var x in list)
{
Console.WriteLine(x);
list.Add(x);
}
So anyone who is talking here about mutability or different confusing layers etc, I think it is completely half implemented feature by Visual Team because enumeration will always cause problems if the collection is modified.
Despite of arguments, I still see a no reason that ForEach should allow modifications, it is purely used for enumeration and it makes no difference whether its foreach(var item in x) syntax or x.ForEach(x=>{}) syntax.
I disagree with Eric, I just see it simply that BCL team has implemented this feature on IEnumerable as well as list.ForEach is faulty.
"Why" is completely subjective,for example, Silverlight has added complex hashing algorithms and left MD5 behind where else everywhere else we use MD5 so widely. Its more of how much anything is in demand and who is the one who chooses whether to include it or not in framework.
There is no logical or philosophical reason at all for not having ForEach in IEnumerable. There are many such missing points which I think .NET will improve over time.