Boş IAsyncEnumerable oluşturun


25

Ben böyle yazılmış bir arayüz var:

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

Hiçbir öğe döndüren boş bir uygulama yazmak istiyorum, şöyle:

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

Düz bir IEnumerable olsaydı return Enumerable.Empty<string>();, isterdim , ama hiç bulamadım AsyncEnumerable.Empty<string>().

Geçici Çözümler

İşe yarayan ama oldukça garip olanı buldum:

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

Herhangi bir fikir?

Yanıtlar:


28

System.Linq.AsyncPaketi yüklerseniz , kullanabilmeniz gerekir AsyncEnumable.Empty<string>(). İşte tam bir örnek:

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

Hemen cevap ve öneriniz için teşekkürler. Çerçevede bir şey olmasını umuyordum.
— cube45

@ cube45: Genellikle System.Linq.Async"çerçevenin neredeyse bir parçası" olarak kabul ederdim . Sadece netstandard2.1'de çok az şey var IAsyncEnumerable<T>.
— Jon Skeet

@ cube45 Paketi kullanmama konusunda dikkatli olurdum Gerçekten ne yaptığınızı bilmiyorsanız, daha çok kullanmaya başladığınızda keşfedeceğiniz asenkron akışları olan birçok kuark vardır.
— Filip Cordas

Cevaplarınız için teşekkürler. Daha önce IAsyncEnumerable'ı hiç kullanmamıştım ve sadece deniyordum, "gerçek için" bir şey yapmıyordum. Muhtemelen haklısınız, paket faydalı olabilir.
— cube45


11

Herhangi bir nedenle Jon'un cevabında belirtilen paketi kurmak istemiyorsanız, aşağıdaki AsyncEnumerable.Empty<T>()gibi bir yöntem oluşturabilirsiniz :

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

Not: Cevap System.Linq.Asyncpaketi kullanmaktan vazgeçmez . Bu yanıt, AsyncEnumerable.Empty<T>()gereksinim duyduğunuz durumlar için kısa bir uygulama sağlar ve paketi kullanmak istemezsiniz. Pakette kullanılan uygulamayı burada bulabilirsiniz .


Cevabınız için teşekkürler. Gerçekten de, bu bir seçenek olurdu. Başka bir paket kurmak yerine bu yolu tercih edeceğimi düşünüyorum. Bunu kabul edilmiş olarak işaretleyeceğim. Nitpick: Statik bir sınıfta yalnızca statik bir yöntemken "genişletme yöntemi" diyorsunuz.
— cube45

1
@ cube45: Peki ilgili asenkron dizilerle herhangi bir LINQ işlevselliği kullanmayı düşünmüyor musunuz? Çünkü normalde senkronize LINQ ile yapacağınız her şeyi yapmak istediğinizde System.Linq.Async'e ihtiyacınız olacak.
— Jon Skeet
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.