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.