foreach
以下に示すループ内で Yield はどのように機能しますか? lstNumbers のタイプはList<int>
です。
foreach (int i in lstNumbers)
{
yield return i;
}
値を受け取ると戻り始めますか、それとも最後に最終的なリストを返しますか?
それはどのように違うのですか:
foreach (int i in lstNumbers)
{
return i;
}
foreach
以下に示すループ内で Yield はどのように機能しますか? lstNumbers のタイプはList<int>
です。
foreach (int i in lstNumbers)
{
yield return i;
}
値を受け取ると戻り始めますか、それとも最後に最終的なリストを返しますか?
それはどのように違うのですか:
foreach (int i in lstNumbers)
{
return i;
}
この例では、すべての値を 1 つずつ返しますが、消費するコードは結果セットの反復処理を開始する必要があります。
foreach (int i in lstNumbers)
{
yield return i;
}
1, 2
コンソールに表示される次の例を見てくださいfor
。消費するコードが列挙型を反復処理しない場合、メソッド内のループは決して終了しません。
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
foreach (var item in Get().Take(2))
{
Console.WriteLine(item);
}
}
static IEnumerable<int> Get()
{
foreach (var item in new[] { 1, 2, 3 })
{
yield return item;
}
}
}
この場合、おそらく何も生成する必要はありませんが、既に結果を取得しているため、単純に結果を返します。
return lstNumbers;
一方、2番目のケースでは:
foreach (int i in lstNumbers)
{
return i;
}
リストの最初の値を返すだけで、反復はすぐに中断されます。
i
最初のケースでは、 への呼び出しの瞬間に単に戻りますreturn i
。
呼び出し元が関数に対して反復子を再度呼び出した後、次の反復にジャンプします。
明確にするための例:
int GetNextNumber() {
foreach (int in in lstNumbers)
{
yield return in; //returns on first hit
}
}
以降
foreach(var i in GetNextNumber()) {
//process number got from the GetNextNumber()
//on next iteration GetNextNumber() will be called again
// so the next number from lstNumbers will be returned
}
これは、長いデータ ストリームを処理するための非常に一般的な方法であり、そのプロセスの一部を順番に選択し、別のプロセスを要求した後などです。
2 番目のケースでは、常にリストの最初の要素を返し、他の要素にジャンプすることはありません。