空のIAsyncEnumerableを作成する


25

私はこのように書かれたインターフェースを持っています:

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

次のように、アイテムを返さない空の実装を記述したいと思います。

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>()

回避策

私はこれがうまくいくのを見つけましたが、かなり奇妙です:

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

何か案が?

回答:


28

System.Linq.Asyncパッケージをインストールすると、を使用できるようになりますAsyncEnumable.Empty<string>()。以下は完全な例です。

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

迅速な返信と提案をありがとう。フレームワークに何かが存在することを期待していました。
cube45

@ cube45:私は一般的にSystem.Linq.Async「実質的にフレームワークの一部」と見なします。非常に少ないということがありますちょうどそれがに来るときnetstandard2.1にIAsyncEnumerable<T>
ジョン・スキート

@ cube45私はパッケージを使用しないように注意します。私が本当にナゲットで何をしているのか本当にわかっていなければ、それをより使い始めるときに発見する非同期フローを持つ多くのクォークがあります。
フィリップコルダス

ご回答ありがとうございます。私はこれまでIAsyncEnumerableを使用したことがなく、単に「実際に」何かを行うのではなく、単に実験を行っていました。あなたはおそらく正しいです、パッケージは役に立つかもしれません。
cube45


11

何らかの理由でJonの回答に記載されているパッケージをインストールしたくない場合は、次のAsyncEnumerable.Empty<T>()ようなメソッドを作成できます。

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>()、パッケージが必要であり、パッケージを使用したくない/したくない場合の簡単な実装を提供します。パッケージ使用されている実装はここにあります


ご回答有難うございます。確かに、それも選択肢になります。私は別のパッケージをインストールするよりもその方法を好むと思います。これを承認済みとしてマークします。Nitpick:静的クラスの静的メソッドであるのに、「拡張メソッド」と言います。
cube45

1
@ cube45:では、非同期シーケンスを伴うLINQ機能を使用する予定はありませんか?同期LINQで通常行うことをすべて実行したいので、System.Linq.Asyncが必要になります。
ジョンスキート
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.