-
Notifications
You must be signed in to change notification settings - Fork 238
Description
Description
Rule S4456 ("Parameter validation in yield methods") is incorrectly raised for async iterator methods returning IAsyncEnumerable<T> because the C# language does not allow applying the compliant fix recommended by the rule.
S4456 suggests splitting the method into:
- an outer method performing parameter validation
- an inner iterator method containing the
yield
This pattern is not expressible for async iterators.
In C#, an async method that returns IAsyncEnumerable<T> must contain a yield return or yield break.
If such a method tries to return the result of another iterator, the compiler produces an error.
Therefore, when S4456 is raised on an async IAsyncEnumerable<T> method, the developer has no possible compliant fix, because C# prohibits the required refactoring.
Expected behavior
Rule S4456 should not be raised for methods returning:
async IAsyncEnumerable<T>
because the recommended fix cannot be implemented due to C# language restrictions.
Reproducer
Code that triggers S4456
public async IAsyncEnumerable<long> GetValuesAsync(int count)
{
if (count <= 0)
throw new ArgumentOutOfRangeException(nameof(count));
await Task.Delay(10);
yield return 1;
}Sonar reports S4456 because parameter validation happens inside an iterator method.
Attempt to apply the compliant pattern (fails to compile)
public async IAsyncEnumerable<long> GetValuesAsync(int count)
{
if (count <= 0)
throw new ArgumentOutOfRangeException(nameof(count));
return Iterator(count);
// ❌ Compiler error:
// Cannot return a value from an iterator. Use the yield return statement to return a value.
}
private async IAsyncEnumerable<long> Iterator(int count)
{
await Task.Delay(10);
yield return 1;
}This demonstrates that the compliant solution required by rule S4456 is not possible for async iterators.
Product and Version
SonarQube Cloud