読者です 読者をやめる 読者になる 読者になる

Code Reading: yield

.NET

『The road to C# master trapemiya』より.

c#2.0でyieldが導入されて、とっても簡単にイテレータが実装できるようになったわけですが、これってどういう仕組みになってるの?と不思議に思った方も多いと思います。実はコルーチンとして振舞っているのです。この辺り、以下のページがとっても参考になりました。ありがとう。感謝、感謝。すっきりしました。

yield キーワード
http://wisdom.sakura.ne.jp/programming/cs/cs2_8.html

今後 yield を使ったコードを目にする機会は増えてくるかと思いますが*1,例えば以下のようなコードの読み方を注意している文献は少ない*2ので注意.

public static IEnumerable<int> One
{
    get
    {
        try
        {
            while (true)
            {
                yield return 1;
            }
        }
        finally
        {
            Console.WriteLine("Stopped!");
        }
    }
}

無限に 1 を返す Enumerator です.中身は無限ループなので一見 finally 句が実行される機会は非常に稀なように見えます.「ThreadAbortException を意図してのものかな?」という読みも,まあ外れとは言えないでしょう.
でもどちらかというと以下のような局面でその影響を目にすることが多いかと思います.

static void Main(string[] args)
{
    try
    {
        Test1();
        Test2();
    }
    catch
    {
    }
}
static void Test1()
{
    foreach (int i in One)
    {
        return;
    }
}
static void Test2()
{
    foreach (int i in One)
    {
        throw new Exception();
    }
}

イテレータ構文の中で例外処理を見たら書き手の意図に注意.

*1:LINQ 方面に走り出した人はむしろ yield を明示的に書く機会が減ってるでしょうけど

*2:例えば @IT の菊池さんの記事『C# 2.0新機能徹底解説(後編)進化したC# 2.0の状態管理、匿名メソッドとイテレータ』「確実な後処理」参照のこと.