c# - 从 C# 中的yield 返回 IEnumerable<T>

标签 c# .net-core async-await ienumerable

我可以编译

public async Task<IEnumerable<T>> GetResultsFromQueryExecutionId<T>(string queryExecutionId)
{
     await using var csvResponseStream = await transferUtility.OpenStreamAsync("bucket", "blah.csv");
     return GetResultsFromResponseStream<T>(csvResponseStream);
}

private IEnumerable<T> GetResultsFromResponseStream<T>(Stream csvResponseStream)
{
     using var streamReader = new StreamReader(csvResponseStream);
     using var csvReader = new CsvReader(streamReader, csvConfiguration);
     foreach (var record in csvReader.GetRecords<T>())
     {
          yield return record;
     }
}

但是,如果我尝试删除私有(private)方法并在一个方法中运行代码,则会收到编译错误“‘GetResultsFromQueryExecutionId’的主体不能是迭代器 block ,因为‘System.Threading.Tasks.Task' 不是异步迭代器接口(interface)类型”

我试过了

public async Task<IEnumerable<T>> GetResultsFromQueryExecutionId<T>(string queryExecutionId, string logPrefix = null)
{
     await using var csvResponseStream = await transferUtility.OpenStreamAsync("bucket", "blah.csv");
     using var streamReader = new StreamReader(csvResponseStream);
     using var csvReader = new CsvReader(streamReader, csvConfiguration);
     foreach (var record in csvReader.GetRecords<T>())
     {
          yield return record;
     }
}

我期望代码是等效的。有谁能够解释为什么编译器不允许我将其合并到一种方法中吗?

最佳答案

the specification 中所写:

The yield statement is used in an iterator block (§13.3) to yield a value to the enumerator object (§15.14.5) or enumerable object (§15.14.6) of an iterator or to signal the end of the iteration.

目前据我所知,编译器支持从使用 yield return 的方法返回以下类型:

IEnumerable
IEnumerator
IEnumerable<T>
IEnumerator<T>
IAsyncEnumerable<T>
IAsyncEnumerator<T>

Task<IEnumerable<T>>不是其中之一,因此您只能使用两种方法或使用 IAsyncEnumerable/IAsyncEnumerator :

private async IAsyncEnumerable<T> GetResultsFromResponseStream<T>(Stream csvResponseStream)
{
    await using var csvResponseStream = ... 
    // the iterator block
}

虽然我个人会使用第一个(为了方便起见,您可以将该方法转换为 local function)。

了解更多:

关于c# - 从 C# 中的yield 返回 IEnumerable<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76689195/

相关文章:

c# - 如何使用自定义标识符启动进程/实例

c# - 无法从 nethereum 解码的输入数据中获取可读整数

c# - 函数的监听器无法启动。为什么?

c# - 使用ftp上传文件

c# - TPL 数据流本地存储或类似的东西

c# - 如何在我的 C# 应用程序中使用其他软件 DLL?

c# - 依赖注入(inject) : What should be injected where?

.net-core - 构建 .NET Core 控制台应用程序以输出 EXE

async-await - 为什么 ReadAsync 在 FileStream 中比在 C# 中的 StreamReader 更快?

JavaScript 在没有resolve() 语句的情况下返回新的 Promise,不会按预期等待