LINQ operations shouldn't have side effects or do actions. They should only be used to produce, from a IEnumerable<T>
another IEnumerable<T>
(or from a IQueryable<T>
another IQueryable<T>
or IEnumerable<T>
) (or if aggregating, like .Max
, .All
... a single result)
Read for example http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx.
(and note that this question is quite asked on SO... Read for example my reply here ToList().ForEach in Linq and see a solution to a similar problem)
Now, if you hate yourself enough, you can do this:
strs.Select((p, index) =>
{
Console.WriteLine("#" + index + " " + "<" + p + ">");
return true;
}).All(p => p);
We are using the .All(p => p)
to "materialize" the Select
operation. This because Select
is "lazy" and won't be executed if no one cycles it.
Technically you could even try to obfuscate it a little:
strs.Select((p, index) =>
{
Console.WriteLine("#" + index + " " + "<" + p + ">");
return false;
}).Any(p => p);
(All
checks that all the elements are true
and stops if one of the is false
, so it has to cycle all of them (because we always return true;
). Any
(as written) checks that at least one of the elements is true
and then stops (but all of our elements are false
, becasue we do return false;
so the Any
will cycle all the elements)
Now... The advantage of these techniques over using ToList
is that we aren't "duplicating" an Array
to a List<T>
just to use a "wrong" method of List<T>
. If the ForEach
method of List<T>
is "wrong", duplicating an Array
to a List
just to use it is doubly-wrong.