Hatena::ブログ(Diary)

地獄の猫日記 このページをアンテナに追加 RSSフィード

2009-04-24

匿名デリゲートのスコープ?

どうやら、匿名デリゲートにおける変数のスコープがどうも俺の直感性と反するようである。

たとえば下記のコード、

public delegate void NoArgDelegate();

static NoArgDelegate[] InitializeOne()

{

NoArgDelegate[] array = new NoArgDelegate[5];

for (int i = 0; i

array[i] = delegate() { Console.WriteLine(i); };

return array;

}

を実行すると、直感的には

0

1

2

3

4

が出力されるように思える。

しかし、実際には

5

5

5

5

5

が出力される。

どうやら匿名デリゲートにおける変数スコープが呼び出し元の変数スコープとは異なるのが原因らしい。

このあたりの詳細について興味がある場合は C# Tutorial - Anonymous Delegates And Scoping が詳しいのでそちらを参照して欲しい。

プログラム言語デザインにおける直感性の大切さ - 続・年中Sage進行

これって匿名デリゲートのスコープ云々の問題じゃなくて、for のスコープの問題なんじゃないの?

for が i を使い回しているから起きるだけじゃ。

つまり、はじめのコードはちょうど以下のコード等価になるんじゃないかと。

public delegate void NoArgDelegate();

static NoArgDelegate[] InitializeOne()
{
  NoArgDelegate[] array = new NoArgDelegate[5];
  {
    int i;
    for (i = 0; i < array.Length; i++)
      array[i] = delegate() { Console.WriteLine(i); };
  }
  return array;
}

C# はろくにやったこともないが多分合ってる。