Linq style For Each
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
People often ask for a "LINQ style ForEach" because they want loop code to look more fluent. The important distinction is that LINQ is designed for querying and transforming sequences, while foreach is the normal C# tool for side effects.
LINQ Does Not Provide ForEach for IEnumerable
There is no built-in ForEach extension method for IEnumerable<T> in standard LINQ. That is intentional. LINQ focuses on returning sequences, not on executing imperative actions against each element.
You can write this:
And that is usually the best answer. It is direct, obvious, and side-effect friendly.
By contrast, LINQ is meant for tasks like filtering or projection:
That query builds a new result. It is not just "loop and do something".
List<T>.ForEach Exists, But It Is Not LINQ
Sometimes people see List<T>.ForEach and assume it is part of LINQ. It is not. It is a method on List<T>.
This works, but only because the source is a List<string>. If you have an IEnumerable<string> from a LINQ query, that method is not available unless you first materialize the sequence:
That extra ToList can be fine, but it means you are paying to allocate a list just to run side effects. Often a plain foreach is clearer and cheaper.
Why foreach Is Usually Better
foreach communicates intent well:
- iterate now
- perform side effects
- no hidden materialization
It also avoids mixing query style with mutation style. Once you start using LINQ methods purely to trigger actions, the code becomes harder to reason about because LINQ's usual mental model is "describe data flow, then enumerate later".
A readable pattern is:
This keeps the transformation and the action separate.
If You Really Want an Extension Method
You can write your own ForEach extension for IEnumerable<T>:
Usage:
This is valid code, but many teams avoid it because it encourages side effects in places where developers expect LINQ-like purity. It also hides enumeration, which matters if the sequence is expensive or lazy.
Deferred Execution Is the Real Subtlety
LINQ queries are often lazy. That means the query does nothing until you enumerate it.
At this point, no numbers have been processed yet. The work happens when you loop:
That is another reason foreach fits naturally with side effects. It is the moment where enumeration actually occurs.
Common Pitfalls
- Thinking
List<T>.ForEachis a LINQ operator. It is a list method. - Converting every sequence to
List<T>only to callForEach, which adds unnecessary allocation. - Hiding side effects inside query operators such as
Select. That makes code misleading. - Forgetting that LINQ queries are often lazy, so nothing happens until enumeration.
- Writing a custom
ForEachextension without considering whether the team wants that style.
Summary
- Standard LINQ does not include
ForEachforIEnumerable<T>. - The normal C# tool for per-item side effects is
foreach. - '
List<T>.ForEachexists, but it is not a LINQ feature and only works on lists.' - A custom extension method is possible, but it can blur the difference between querying and side effects.
- In most codebases,
foreachremains the clearest and most idiomatic answer.

