Big Subjective Question: I often find myself using LINQ to filter a set of objects and then, after the query, doing an old fashion foreach to perform an action on each of the results. Is there a good way of combining these two tasks such that an action is performed on each object that matches the Where() predicate? Almost like passing an Action into the Select(). That probably would not compile, but what about passing in a Func that returns a bool, then you could nest that inside another query that could do something with the failures or successes. Has anyone done this in production code? Would this be considered bad practice? Any other thoughts?
3 Answers
Many people have asked for a ForEach
method - and indeed it is handy (which is why we've got one in MoreLINQ). It's also potentially dangerous.
Most of LINQ firmly discourages side-effects. They're possible, but discouraged. That's why OrderBy etc return new collections rather than sorting existing ones.
Now consider ForEach
- it's an "action" rather than a function, in that it doesn't return anything. If it doesn't have any side-effects, it's absolutely pointless! So, it goes against part of the philosophy of LINQ - it's basically not approaching things in a functional style.
I'm not trying to make a case for or against, really - in practice, I think a useful thing to have, and I'm not surprised that it's in so many libraries etc. It's a very obvious pseudo-operator to add. Just think about what you're doing, and notice the fact that you're introducing side-effects. It's sort of a border between the functional style of LINQ and a more imperative style of coding.

- 1,421,763
- 867
- 9,128
- 9,194
-
I didn't know about MoreLINQ up until now. It's now referenced, and your ForEach is used instead of my homegrown Each. Thanx! – Martin R-L Dec 09 '09 at 13:07
-
Great explanation on why it is not implemented on IEnumerable
. Thanks! – Thomas May 06 '10 at 09:30
-
I've added my own extension method named Each() to IEnumerable
that does the same. – Martin R-L Dec 08 '09 at 15:13