2

デリゲート関数が渡されたデータリーダーを処理する非同期メソッドがあります。デリゲートの目的は、リーダーからドメイン オブジェクトを構築し、それらを呼び出し元に返すことです。デリゲートとリーダーを構築し、呼び出されたメソッドから結果の IAsyncEnumerable を返す中間メソッドが必要です。これを実現できた唯一の方法は、実際に IAsyncEnumerable を消費し、中間メソッドからそれらの結果を生成することです。直接返そうとすると、yield return または yield break を使用する必要があるというコンパイラ エラーが発生します。

delegate T ProcessFunc<T>(MySqlDataReader reader);

async IAsyncEnumerable<T> ProcessReader<T>(MySqlDataReader reader, ProcessFunc<T> transformFunc)
{
    while (await reader.ReadAsync() != false)
    {
        yield return transformFunc(reader);
    }

    await reader.DisposeAsync();
}

public async IAsyncEnumerable<DataObject> GetDataObjectsAsync()
{
    ProcessFunc<DataObject> processFunc = (reader) =>
    {
        var id = reader.GetGuid( "id" );

        return new DataObject(id);
    };

    var reader = await GetDataObjectsReaderAsync(); //Constructs appropriate sqlcommand and returns a mysqldatareader

    //only way i can get this to function
    //would like to just be able to write: return ProcessReader(reader, processFunc)
    //so as not to chain another enumerable
    await foreach (var obj in ProcessReader( reader, processFunc ))
        yield return obj; 
}
4

1 に答える 1