【问题标题】:Is there a way to return an IAsyncEnumerable without using await foreach有没有办法在不使用 await foreach 的情况下返回 IAsyncEnumerable
【发布时间】:2019-11-14 18:03:08
【问题描述】:

在 MethodB 的返回签名是 IAsyncEnumerable 的情况下,并且它是从 MethodA 内部调用的,是否可以返回一个 IAsyncEnumerable,而无需迭代 MethodB 的返回值,如下所示:

IAsyncEnumerable<T> MethodB() => do stuff;

IAsyncEnumerable<T> MethodA() => return MethodB(); <- this gives a compiler error: must use yield return;

根据错误消息,我认为唯一的方法如下:

async IAsyncEnumerable<T> MethodA() => await foreach(var t in MethodB())yield return t;

【问题讨论】:

    标签: c#


    【解决方案1】:

    您只是对MethodA 使用了错误的语法 - 您正在使用表达式主体成员返回语句。您可以使用块体成员:

    IAsyncEnumerable<T> MethodB() => null;
    
    IAsyncEnumerable<T> MethodA()
    {
        return MethodB();
    }
    

    或者只是删除return 声明:

    IAsyncEnumerable<T> MethodB() => null;
    
    IAsyncEnumerable<T> MethodA() => MethodB();
    

    这并不是IAsyncEnumerable&lt;T&gt; 所特有的——只是返回类型给了你一个比你通常得到的更令人困惑的错误消息:

    // Invalid expression term 'return'
    int Method() => return 0;
    

    【讨论】:

    • 在我的代码中尝试了表达式语法后,结果发现使用带有异步修饰符的块体成员会产生相同的编译器错误,而表达式体成员则不会。是否有某些原因将这两者区别对待?
    • @cubesnyc:这有点令人惊讶,但我不明白你为什么要在那里使用async 修饰符,至少对于这个简单的情况。看起来编译器假定任何具有异步可枚举返回类型的 async 方法都是迭代器 - 我 怀疑 这是一个错误,但我不确定。请注意,如果您将返回类型声明为Task&lt;IAsyncEnumerable&lt;T&gt;&gt;,那就没问题了。如果您有具体示例说明为什么在这种情况下想要在方法上使用async,我可以提供更多详细信息。不过,也许可以在一个单独的问题中问它。
    猜你喜欢
    • 1970-01-01
    • 2017-01-27
    • 2016-01-10
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多