ループせずに、yield returnですべての列挙型を一度に返します。質問する

ループせずに、yield returnですべての列挙型を一度に返します。質問する

カードの検証エラーを取得する次の関数があります。私の質問は GetErrors の処理に関するものです。両方のメソッドの戻り値の型は同じですIEnumerable<ErrorInfo>

private static IEnumerable<ErrorInfo> GetErrors(Card card)
{
    var errors = GetMoreErrors(card);
    foreach (var e in errors)
        yield return e;
    
    // further yield returns for more validation errors
}

GetMoreErrorsエラーを列挙せずに、すべてのエラーを返すことは可能ですか?

ベストアンサー1

yield!これは、F# がコレクション全体と単一の項目の両方に対してサポートしている機能ですyield。(末尾再帰の観点から非常に便利です...)

残念ながら、C# ではサポートされていません。

ただし、それぞれが を返すメソッドが複数ある場合はIEnumerable<ErrorInfo>、 を使用してEnumerable.Concatコードを簡素化できます。

private static IEnumerable<ErrorInfo> GetErrors(Card card)
{
    return GetMoreErrors(card).Concat(GetOtherErrors())
                              .Concat(GetValidationErrors())
                              .Concat(AnyMoreErrors())
                              .Concat(ICantBelieveHowManyErrorsYouHave());
}

しかし、2つの実装の間には1つの非常に重要な違いがあります。これは、すべてのメソッドを呼び出すことです。すぐに返されたイテレータを一度に1つだけ使用するにもかかわらず、既存のコードは、すべてのループが完了するまで待機しますGetMoreErrors()尋ねる次のエラーについて。

通常、これは重要ではありませんが、いつ何が起こるかを理解しておく価値はあります。

おすすめ記事