web-dev-qa-db-ja.com

C#:リターン範囲/コレクションを生成します

yield returnキーワードをかなり使用していますが、IEnumerableに範囲を追加したいときに不足していることがわかりました。これが私がやりたいことの簡単な例です:

IEnumerable<string> SomeRecursiveMethod()
{
    // some code 
    // ...
    yield return SomeRecursiveMethod();
}

当然、これによりエラーが発生します。これは、単純なループを実行することで解決できます。これを行うためのより良い方法はありますか?ループは少し不格好に感じます。

44

いいえ、恐れることはありません。 F#doesyield!でこれをサポートしますが、C#には同等のものはありません-基本的にループを使用する必要があります。すみません...あなたの痛みを感じます。 私のEdulinqブログ投稿の1つ で言及しましたが、ここでは物事が簡単になります。

利回りリターンを再帰的に使用するとコストがかかる可能性があることに注意してください-詳細については Wes Dyerのイテレータに関する投稿 を参照してください(4年前に検討されていた「yieldforeach」について言及しています...)

48
Jon Skeet

ループオーバーするIEnumerableがすでにあり、戻り値の型がIEnumerableの場合(yield returnを使用できる関数の場合のように)、単にその列挙を返すことができます。

複数のIEnumerablesの結果を組み合わせる必要がある場合は、IEnumerable<T>.Concat拡張メソッドを使用できます。

ただし、再帰的な例では、列挙の内容に基づいて列挙/連結を終了する必要があります。私の方法はこれをサポートするとは思わない。

Yieldキーワードは確かにとてもいいです。ただし、forループにネストすると、より多くのグルーコードが生成および実行されます。

機能性の低いプログラミングスタイルで生活できる場合は、追加するリストを渡すことができます。

 void GenerateList(List<string> result)
 {

      result.Add("something")

      // more code.

      GenerateList(result);

 }
0
user180326