ToListForEach
Diagnostic Rule Overview
Field | Value |
---|---|
ID | SHIMMER1010 |
Analyzer title | .ToList().ForEach() causes unnecessary memory allocation |
Analyzer message | Replace .ToList().ForEach() with a foreach loop to reduce memory usage |
Code fix title | Replace with a foreach loop |
Default severity | Warning |
Minimum framework/language version | N/A |
Category | ShimmeringUsage |
Link to code | ToListForEachAnalyzer.cs |
Code fix exists? | Yes |
Detailed Explanation
Avoid converting an IEnumerable<T>
to a List<T>
just to use the List<T>.ForEach()
method. The unnecessary .ToList()
call causes extra memory allocation, while a simple foreach
loop achieves the same result without this overhead. If you do want to a list, you can work around this diagnostic by using a plain foreach
loop.
Note that this diagnostic is not triggered if the preceding enumerable implements IQueryable<T>
, as using .ToList()
for materialization is a valid use case.
Examples
Flagged code:
using System;
using System.Linq;
namespace Tests;
class Test
{
void Do(int[] numbers)
{
numbers.ToList().ForEach(n => Console.WriteLine(n));
}
}
Fixed code:
using System;
using System.Linq;
namespace Tests;
class Test
{
void Do(int[] numbers)
{
foreach (var n in numbers)
{
Console.WriteLine(n);
}
}
}
Justification of the Severity
While this is not a bug, this will slow down your code and increase memory usage with no benefits. As a reminder, the diagnostic doesn't flag if the preceding enumerable implements IQueryable<T>
, which is likely the main case where you'd actually want to allocate a list.
Related Rules
- SHIMMER1011: Unnecessary materialization to array/list in LINQ chain
- SHIMMER1012: An array creation expression or array-returning method should not be followed by .ToArray()
Inspiration
This was inspired by @Treit's blog post https://mtreit.com/programming,/.net/2024/07/30/ToList.html. The same material was also covered in this YouTube video.