After C# 5 introduced the async
and await
model for asynchronous programming, the C# community arrived at a naming convention to add an "Async" suffix to methods returning an awaitable type, like this:
interface Foo
{
Task BarAsync();
}
Many static code analyzers (both Roslyn-based and non-Roslyn-based) have since been written to depend on this naming convention when detecting code smell around asynchronous programming.
Now that C# 8 has introduced the concept of asynchronous enumerables, which themselves are not awaitable but can be used in conjunction with await foreach
, there seems to be two options for naming methods returning IAsyncEnumerable
:
interface Foo
{
// No "Async" suffix, indicating that the return value is not awaitable.
IAsyncEnumerable<T> Bar<T>();
}
or
interface Foo
{
// With "Async" suffix, indicating that the overall logic is asynchronous.
IAsyncEnumerable<T> BarAsync<T>();
}
Has there been a definitive naming convention guideline (from the C# language team, the .NET Foundation, or other authorities) regarding the options above, like how the C# 5 naming convention was unambiguously standardized and not left to opinion-based judgement of programmers?
There's no better guideline than what the .NET teams already do :
IAsyncEnumerable<T>
IAsyncEnumerable
by calling AsAsyncEnumerable()
IAsyncEnumerable
sSystem.Linq.Async
retain their names. There's no SelectAsync
or SelectAsAsyncEnumerable
, just Select
. In all cases, it's clear what the result of the method is. In all cases, the results of the method need to be awaited with await foreach
before they can be used.
So the real guideline remains the same - ensure the name makes the behavior clear:
AsAsyncEnumerable()
or ToAsyncEnumerable()
, there's no need to add any suffix. Async
suffix so developers know they need to await foreach
the result.The code analyzers and generators don't really care about the names of methods, they detect smells by inspecting the code itself. A code analyzer will tell you that you forgot to await a Task or await foreach
an IAsyncEnumerable
no matter how you call the methods and the variables. A generator can simply use reflection to check for IAsyncEnumerable
and emit await foreach
It's the style analyzers that check names. Their job is to ensure the code uses a consistent style so developers can understand the code. The style analyzer will tell you that a method doesn't follow the style you chose. That style may be the team's or a commonly accepted style guide.
And of course, everyone knows the common prefix for private instance fields is _
:)
It’s not an async method, so the name shouldn’t end in ‘Async’. That method suffix is a convention to make it obvious that the method should be awaited, or the result handled as a Task.
I think a normal collection-returning name is appropriate. GetFoos(), or similar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With