web-dev-qa-db-fra.com

Créer un IAsyncEnumerable vide

J'ai une interface qui est écrite comme ceci:

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

Je veux écrire une implémentation vide qui ne renvoie aucun élément, comme ceci:

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

Si c'était un simple IEnumerable, je ferais return Enumerable.Empty<string>();, mais je n'ai trouvé aucun AsyncEnumerable.Empty<string>().

Solutions de contournement

J'ai trouvé cela qui fonctionne mais qui est assez bizarre:

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

Une idée?

24
cube45

Si vous installez le package System.Linq.Async , vous devriez pouvoir utiliser AsyncEnumable.Empty<string>(). Voici un exemple complet:

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
    }
}
26
Jon Skeet

Si pour une raison quelconque, vous ne souhaitez pas installer le package mentionné dans la réponse de Jon, vous pouvez créer la méthode AsyncEnumerable.Empty<T>() comme ceci:

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);
    }
}

Remarque: La réponse ne décourage pas l'utilisation du package System.Linq.Async. Cette réponse fournit une brève implémentation de AsyncEnumerable.Empty<T>() pour les cas où vous en avez besoin et que vous ne pouvez/ne voulez pas utiliser le package. Vous pouvez trouver l'implémentation utilisée dans le package ici .

10
Reza Aghaei