创建空的IAsyncEnumerable


25

我有一个这样写的接口:

public interface IItemRetriever
{
    public IAsyncEnumerable<string> GetItemsAsync();
}

我想编写一个不返回任何项目的空实现,如下所示:

public class EmptyItemRetriever : IItemRetriever
{
    public IAsyncEnumerable<string> GetItemsAsync()
    {
       // What do I put here if nothing is to be done?
    }
}

如果可以使用普通的IEnumerable,我可以return Enumerable.Empty<string>();,但是没有找到任何东西AsyncEnumerable.Empty<string>()

解决方法

我发现这可行,但是很奇怪:

public async IAsyncEnumerable<string> GetItemsAsync()
{
    await Task.CompletedTask;
    yield break;
}

任何的想法?

Answers:


28

如果安装该System.Linq.Async软件包,则应该可以使用AsyncEnumable.Empty<string>()。这是一个完整的示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        IAsyncEnumerable<string> empty = AsyncEnumerable.Empty<string>();
        var count = await empty.CountAsync();
        Console.WriteLine(count); // Prints 0
    }
}

感谢您的及时答复和建议。我希望框架中存在某些东西。
cube45

@ cube45:我通常将其System.Linq.Async视为“实际上是框架的一部分”。有很少这只是在netstandard2.1当谈到IAsyncEnumerable<T>
乔恩·斯基特

@ cube45我会小心不要使用该包,除非您真的知道自己在做什么,否则当您开始使用它时,会发现许多带有异步流的夸克,除非您真的知道我在做什么。
Filip Cordas

感谢您的回答。我以前从未使用过IAsyncEnumerable,而我只是在做实验,而不是“真正地”做某事。您可能是对的,该软件包可能很有用。
cube45

如果它与efcore 一起
Pavel Shastov

11

如果由于某种原因您不想安装Jon的答案中提到的软件包,则可以创建如下方法AsyncEnumerable.Empty<T>()

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public static class AsyncEnumerable
{
    public static IAsyncEnumerator<T> Empty<T>() => EmptyAsyncEnumerator<T>.Instance;

    class EmptyAsyncEnumerator<T> : IAsyncEnumerator<T>
    {
        public static readonly EmptyAsyncEnumerator<T> Instance = 
            new EmptyAsyncEnumerator<T>();
        public T Current => default!;
        public ValueTask DisposeAsync() => default;
        public ValueTask<bool> MoveNextAsync() => new ValueTask<bool>(false);
    }
}

注意:答案不鼓励使用该System.Linq.Async软件包。此答案为AsyncEnumerable.Empty<T>()您需要且无法/不想使用该程序包的情况提供了简短的实现。您可以在此处找到包中使用的实现。


感谢您的回答。确实,这也是一种选择。我认为我更喜欢这种方式,而不是安装另一个软件包。我将此标记为已接受。Nitpick:您说“扩展方法”,而它只是静态类中的静态方法。
cube45

1
@ cube45:因此,您是否不打算将任何LINQ功能与涉及的异步序列一起使用?因为只要您想使用同步LINQ做任何通常需要做的事情,就需要System.Linq.Async。
乔恩·斯基特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.