我一直在学习C#,并且试图理解lambda。在下面的此示例中,它打印出10十次。
class Program { delegate void Action(); static void Main(string[] args) { List<Action> actions = new List<Action>(); for (int i = 0; i < 10; ++i ) actions.Add(()=>Console.WriteLine(i)); foreach (Action a in actions) a(); } }
显然,在lambda后面生成的类正在存储对该int i变量的引用或指针,并在每次循环迭代时都将新值分配给相同的引用。有没有办法强迫lamda代替副本,例如C ++ 0x语法
int i
[&](){ ... } // Capture by reference
与
[=](){ ... } // Capture copies
编译器正在做的是将您的lambda和lambda捕获的任何变量拉入编译器生成的嵌套类。
编译后,您的示例如下所示:
class Program { delegate void Action(); static void Main(string[] args) { List<Action> actions = new List<Action>(); DisplayClass1 displayClass1 = new DisplayClass1(); for (displayClass1.i = 0; displayClass1.i < 10; ++displayClass1.i ) actions.Add(new Action(displayClass1.Lambda)); foreach (Action a in actions) a(); } class DisplayClass1 { int i; void Lambda() { Console.WriteLine(i); } } }
通过在for循环中进行复制,编译器将在每次迭代中生成新对象,如下所示:
for (int i = 0; i < 10; ++i) { DisplayClass1 displayClass1 = new DisplayClass1(); displayClass1.i = i; actions.Add(new Action(displayClass1.Lambda)); }