yield returnを表面的に理解

<はじめに>
LINQについて調べていると、ところどころに出てくる

yield return hogehoge...

この「yield」というのがいまいちピンとこない!
そこでmsdnのドキュメントを眺めていると、いいのがありました!

反復子 (C# および Visual Basic)
Yield または yield return ステートメントに到達すると、コードの現在の位置が保持されます。 実装はその位置から反復子関数が呼び出されるときに再起動されます。

うーん…文章を眺めていてもわかりづらいので、実際に書いてみることに。


<プログラム1>

class Program
{
    static void Main(string[] args)
    {
        foreach (int number in SomeNumbers())
        {
            Console.Write(number.ToString() + " ");
        }
    }

    public static System.Collections.IEnumerable SomeNumbers()
    {
        yield return 3;
        yield return 5;
        yield return 8;
    }
}


<実行結果1>
f:id:nomurabbit:20131018000345p:plain


ほうほう!

ということは、こんな感じにしたら…


<プログラム2>

class Program
{
    static void Main(string[] args)
    {
        foreach (int number in SomeNumbers())
        {
            Console.Write(number.ToString() + " ");
        }
    }

    public static System.Collections.IEnumerable SomeNumbers()
    {
        for (int i = 0; i < 5; i++)
        {
            yield return i;
        }
    }
}


<実行結果2>
f:id:nomurabbit:20131018000541p:plain


なるほど、そういうことか!


<まとめ>
yield returnを表面的な理解の元日本語で書くとすると、
「呼び出し元からループで呼ばれると、
 呼ばれた側は前回呼ばれたyieldの位置を覚えていて、
 その次の文から処理を再開する」
ということですね。