首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建空IAsyncEnumerable

创建空IAsyncEnumerable
EN

Stack Overflow用户
提问于 2019-12-22 10:29:12
回答 3查看 12.7K关注 0票数 42

我有一个界面是这样写的:

代码语言:javascript
复制
public interface IItemRetriever
{
    public IAsyncEnumerable<string> GetItemsAsync();
}

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

代码语言:javascript
复制
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>()

解决办法

我发现这个很管用,但很奇怪:

代码语言:javascript
复制
public async IAsyncEnumerable<string> GetItemsAsync()
{
    await Task.CompletedTask;
    yield break;
}

有什么想法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-12-22 10:45:56

如果您安装了System.Linq.Async包,您应该能够使用AsyncEnumable.Empty<string>()。下面是一个完整的例子:

代码语言:javascript
复制
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
    }
}
票数 56
EN

Stack Overflow用户

发布于 2019-12-22 11:33:01

如果出于任何原因,您不希望安装琼恩的答案中提到的包,您可以创建如下方法AsyncEnumerable.Empty<T>()

代码语言:javascript
复制
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>()的简单实现,用于您需要它的情况,并且您不能/不想使用这个包。您可以找到包这里中使用的实现。

票数 22
EN

Stack Overflow用户

发布于 2021-05-14 16:05:27

我想避免安装System.Linq.Async (因为它的命名空间冲突问题),但是先前的回答实际上并没有按照最初问题中的要求实现IAsyncEnumerable<T>。这里有一个完整的解决方案,它实现了这个接口,以便很容易地以与现在的AsyncEnumerable.Empty<T>相同的方式调用Enumerable.Empty<T>

代码语言:javascript
复制
public static class AsyncEnumerable
{
    /// <summary>
    /// Creates an <see cref="IAsyncEnumerable{T}"/> which yields no results, similar to <see cref="Enumerable.Empty{TResult}"/>.
    /// </summary>
    public static IAsyncEnumerable<T> Empty<T>() => EmptyAsyncEnumerator<T>.Instance;

    private class EmptyAsyncEnumerator<T> : IAsyncEnumerator<T>, IAsyncEnumerable<T>
    {
        public static readonly EmptyAsyncEnumerator<T> Instance = new EmptyAsyncEnumerator<T>();
        public T Current => default;
        public ValueTask DisposeAsync() => default;
        public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            return this;
        }
        public ValueTask<bool> MoveNextAsync() => new ValueTask<bool>(false);
    }
}
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59443429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档