我可以编译
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
我试过了
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/