首页 > 解决方案 > 返回 IAsyncEnumerable 的方法是否有明确的命名约定?

问题描述

在 C# 5 为异步编程引入asyncandawait模型之后,C# 社区达成了一种命名约定,为返回可等待类型的方法添加“Async”后缀,如下所示:

interface Foo
{
   Task BarAsync();
}

许多静态代码分析器(基于 Roslyn 的和非基于 Roslyn 的)在检测异步编程周围的代码异味时都依赖于这种命名约定。

既然 C# 8 已经引入了异步枚举的概念,它本身是不可等待的,但可以与 结合使用await foreach,命名方法返回似乎有两种选择IAsyncEnumerable

interface Foo
{
    // No "Async" suffix, indicating that the return value is not awaitable.
    IAsyncEnumerable<T> Bar<T>();
}

或者

interface Foo
{
    // With "Async" suffix, indicating that the overall logic is asynchronous.
    IAsyncEnumerable<T> BarAsync<T>();
}

是否有关于上述选项的明确命名约定指南(来自 C# 语言团队、.NET 基金会或其他权威机构),例如 C# 5 命名约定如何明确标准化并且不留给程序员基于意见的判断?

标签: c#c#-8.0

解决方案


没有比 .NET 团队已经做的更好的指导方针了:

  • ChannelReader.ReadAllAsync返回一个IAsyncEnumerable<T>
  • IAsyncEnumerable在 EF Core 3 中,通过调用AsAsyncEnumerable()返回结果
  • 在 System.Linq.Async 中,ToAsyncEnumerable()将 IEnumerables、Tasks 和 Observables 转换为IAsyncEnumerables
  • 所有其他运营商都System.Linq.Async保留其名称。没有SelectAsyncSelectAsAsyncEnumerable,只有Select

在所有情况下,很清楚该方法的结果是什么。在所有情况下,都需要等待方法的结果await foreach才能使用。

所以真正的指导方针保持不变 -确保名称使行为清晰

  • 当名称已经明确时,例如使用AsAsyncEnumerable()or ToAsyncEnumerable(),则无需添加任何后缀。
  • 在其他情况下,添加Async后缀,以便开发人员知道他们需要await foreach结果。

代码分析器和生成器并不真正关心方法的名称,它们通过检查代码本身来检测气味。代码分析器会告诉您,无论您如何调用方法和变量,您都忘记await foreach了等待任务。IAsyncEnumerable生成器可以简单地使用反射来检查IAsyncEnumerable和发射await foreach

检查名称的是样式分析器。他们的工作是确保代码使用一致的风格,以便开发人员能够理解代码。样式分析器会告诉您方法不符合您选择的样式。这种风格可能是团队的或普遍接受的风格指南。

当然,每个人都知道私有实例字段的通用前缀是_:)


推荐阅读