Skip to main content

SingleUseIEnumerableMaterialization

Diagnostic Rule Overview

FieldValue
IDSHIMMER1015
Analyzer titleAvoid materializing a single-use IEnumerable
Analyzer messageAvoid materializing an IEnumerable if it's used only once
Code fix titleRemove unnecessary materialization
Default severityInfo
Minimum framework/language versionN/A
Enabled by default?No
CategoryShimmeringUsage
Link to codeSingleUseIEnumerableMaterializationAnalyzer.cs
Code fix exists?Yes

Detailed Explanation

Materializing an IEnumerable<T> when it's only used once is wasteful, as it forces an unnecessary allocation. Therefore, this diagnostic flags an enumerable that is used only once and that usage is either in a foreach loop or followed by a LINQ method.

Currently, this diagnostic is triggered only for a local variable declaration with an implicit type (var), where materialization is done through either .ToArray() or .ToList().

Note that this diagnostic is not triggered if:

  1. the preceding enumerable implements IQueryable<T>, as materialization was likely an intentional decision
  2. the enumerable is used in a lambda (e.g. .Where(x => notFlaggedEnumerable.Contains(x)))

Examples

Flagged code:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Tests;
class Test
{
void Do()
{
List<int> numbers = [];
var oddNumbers = numbers.Where(n => n % 2 == 1).ToArray();
foreach (var oddNumber in oddNumbers)
{
Console.WriteLine(oddNumber);
}
}
}

Fixed code:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Tests;
class Test
{
void Do()
{
List<int> numbers = [];
var oddNumbers = numbers.Where(n => n % 2 == 1);
foreach (var oddNumber in oddNumbers)
{
Console.WriteLine(oddNumber);
}
}
}

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> or if the enumerable is referenced multiple times, which are the main cases where you'd actually want to materialize an enumerable.

When to Suppress

Suppress this diagnostic if the enumerable is actually used multiple times. As a reminder, this diagnostic is not triggered if the enumerable is used in a lambda.