C# delegateとループ変数
delegateからループ変数のアクセスには注意がいる
以下のプログラムは"0"から"4"までの変数の出力させる事を意図して書いたが
実際に出力されるのは"5"が5回だ
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { foreach (Action actor in GenActors()) { actor(); } Console.ReadLine(); } static List<Action> GenActors() { List<Action> result = new List<Action>(); for (int i = 0; i < 5; ++i) { result.Add(delegate() { Console.WriteLine(i); }); } return result; } } }
5 5 5 5 5
しかし以下のようにループ変数を別の変数に入れ替えるとうまく動作する
static List<Action> GenActors() { List<Action> result = new List<Action>(); for (int i = 0; i < 5; ++i) { int j = i; result.Add(delegate() { Console.WriteLine(j); }); } return result; }
0 1 2 3 4
ちなみにyield returnにしてもうまくいく
static IEnumerable<Action> GenActors() { for (int i = 0; i < 5; ++i) { yield return delegate() { Console.WriteLine(i); }; } }
0 1 2 3 4
ということで内部delegate使うときは
うまく変数をバインドしてるかテストしてみてね