Buat IAsyncEnumerable kosong


25

Saya memiliki antarmuka yang ditulis seperti ini:

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

Saya ingin menulis implementasi kosong yang tidak mengembalikan item, seperti:

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

Jika itu adalah IEnumerable biasa, saya akan melakukannya return Enumerable.Empty<string>();, tetapi saya tidak menemukannya AsyncEnumerable.Empty<string>().

Penanganan masalah

Saya menemukan ini yang berfungsi tetapi cukup aneh:

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

Ada ide?

Jawaban:


28

Jika Anda menginstal System.Linq.Asyncpaket, Anda harus dapat menggunakannya AsyncEnumable.Empty<string>(). Ini contoh lengkapnya:

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

Terima kasih atas balasan secepatnya dan sarannya. Saya berharap ada sesuatu dalam kerangka itu.
— cube45

@ cube45: Saya biasanya menganggap System.Linq.Async"hampir bagian dari kerangka kerja". Ada sangat sedikit yang hanya di netstandard2.1 ketika datang ke IAsyncEnumerable<T>.
— Jon Skeet

@ cube45 Saya akan berhati-hati tentang tidak menggunakan paket ada banyak quark dengan aliran async Anda akan menemukan ketika Anda mulai menggunakannya lebih banyak kecuali Anda benar-benar tahu apa yang Anda lakukan, saya akan benar-benar di nugget.
— Filip Cordas

Terima kasih atas jawaban anda Saya tidak pernah menggunakan IAsyncEnumerable sebelumnya, dan saya hanya bereksperimen, tidak melakukan sesuatu yang "nyata". Anda mungkin benar, paket itu mungkin berguna.
— cube45

Ada masalah jika sedang digunakan dengan efcore github.com/dotnet/efcore/issues/18124
— Pavel Shastov

11

Jika karena alasan apa pun Anda tidak ingin menginstal paket yang disebutkan dalam jawaban Jon, Anda dapat membuat metode AsyncEnumerable.Empty<T>()seperti ini:

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

Catatan: Jawabannya tidak mengecilkan hati menggunakan System.Linq.Asyncpaket. Jawaban ini memberikan implementasi singkat AsyncEnumerable.Empty<T>()untuk kasus-kasus yang Anda butuhkan dan Anda tidak bisa / tidak ingin menggunakan paket. Anda dapat menemukan implementasi yang digunakan dalam paket di sini .


Terima kasih atas jawaban anda. Memang, itu akan menjadi pilihan juga. Saya pikir saya lebih suka cara itu daripada menginstal paket lain. Saya akan menandai yang ini sebagai diterima. Nitpick: Anda mengatakan "metode ekstensi" sementara itu hanya metode statis di kelas statis.
— cube45

1
@ cube45: Jadi, apakah Anda tidak berencana menggunakan fungsionalitas LINQ dengan urutan asinkron yang terlibat? Karena begitu Anda ingin melakukan apa pun yang biasanya Anda lakukan dengan LINQ sinkron, Anda akan memerlukan System.Linq.Async.
— Jon Skeet
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.