Using explicit loops for filtering, selecting, or aggregating elements can make code more verbose and harder to read. LINQ expressions provide a more concise and expressive way to perform these operations, improving code clarity and maintainability.
If the affected code is part of a performance-critical hot path and that the fix would negatively impact performance, you can self-declare the
PerformanceSensitiveAttribute in your codebase, or use the one provided by Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers:
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true, Inherited = false)]
public sealed class PerformanceSensitiveAttribute() : Attribute;
[PerformanceSensitiveAttribute]
List<string> Method(IEnumerable<string> collection, Predicate<string> condition)
{
var result = new List<string>();
foreach (var element in collection) // Without the attribute, this would raise an issue
{
if (condition(element))
{
result.Add(element);
}
}
return result;
}
The rule will respect the AllowGenericEnumeration
property:
[PerformanceSensitive("Enumeration", AllowGenericEnumeration = true)]
List<string> Method(IEnumerable<string> collection, Predicate<string> condition) { }
In this case, the rule will not be disabled even if the method is marked with the PerformanceSensitiveAttribute attribute.
Replace explicit loops and conditional blocks with equivalent LINQ expressions.
Use the System.Linq.Async package to enable LINQ operations on IAsyncEnumerable prior to .NET 10.
List<string> Method(IEnumerable<string> collection, Predicate<string> condition)
{
var result = new List<string>();
foreach (var element in collection) // Noncompliant
{
if (condition(element))
{
result.Add(element);
}
}
return result;
}
List<string> Method(IEnumerable<MyDto> collection)
{
var result = new List<string>();
foreach (var element in collection) // Noncompliant
{
var someValue = element.Property;
if (someValue != null)
{
result.Add(someValue);
}
}
return result;
}
public void Method(List<string> list)
{
foreach (var element in list)
{
var someValue = element.Length;
}
}
async void Method(IAsyncEnumerable<int> collection)
{
await foreach (var element in collection)
{
if (element is 42)
{
Console.WriteLine("The meaning of Life.");
}
}
}
List<string> Method(IEnumerable<string> collection, Predicate<string> condition) => collection.Where(x => condition(x)).ToList();
List<string> Method(IEnumerable<MyDto> collection) => collection.Select(x => x.Property).Where(y => y != null).ToList();
void Method(List<int> list)
{
foreach (var length in list.Select(x => x.Length))
{
var someValue = length;
}
}
async void Method(IAsyncEnumerable<int> collection)
{
await foreach (var element in collection.Where(x => x is 42)))
{
Console.WriteLine("The meaning of Life.");
}
}