If we look to the two following examples:
static class Compliant
{
public static bool IsMatch(IEnumable<string> labels, (ReadOnlySpan<char> value)
{
foreach (var label in labels) // FP: by ref structs can not appear in lambda expressions, anonymous functions etc..
{
if (label.AsSpan().Equals(value)) return true;
}
return false;
}
public static T? FirstOrNone<T>(this IEnumerable<T> enumerable, Predicate<T> predicate) where T : struct
{
foreach (var element in enumerable) // FP
{
if (predicate(element))
{
return element;
}
}
return null;
}
}
Reported by SonarAnalyzer.CSharp v10.7.0.110445
The latter might be rewritten as:
static class Compliant
{
public static T? FirstOrNone<T>(this IEnumerable<T> enumerable, Predicate<T> predicate) where T : struct
{
var enumerator = enumerable.GetEnumerator();
while (enumerator.MoveNext())
{
if (predicate(enumerator.Current))
{
return enumerator.Current;
}
}
return null;
}
}
But I would argue that the code is harder to read than before the refactoring.