2

foreach以下に示すループ内で Yield はどのように機能しますか? lstNumbers のタイプはList<int>です。

foreach (int i in lstNumbers)
{
    yield return i;
}

値を受け取ると戻り始めますか、それとも最後に最終的なリストを返しますか?

それはどのように違うのですか:

   foreach (int i in lstNumbers)
    {
        return i;
    }
4

2 に答える 2

1

この例では、すべての値を 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;
}

リストの最初の値を返すだけで、反復はすぐに中断されます。

于 2013-02-17T16:57:52.307 に答える
0

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 番目のケースでは、常にリストの最初の要素を返し、他の要素にジャンプすることはありません。

于 2013-02-17T16:56:47.503 に答える