经典闭包
先看常见的问题
internal class Program { static void Main(string[] args) { var actions = GetSomeAction(); for (int i = 0; i < actions.Count; i++) actions[i](); } static List<Action> GetSomeAction() { var result = new List<Action>(); for (int i = 0; i < 5; i++) result.Add(() => Console.WriteLine(i)); return result; } }
返回结果全是 5 5 5 5 5 并不是正常的想要的 0 1 2 3 4
也许你会说 这就是有问题的呀!那么 什么时候一定有问题?什么情况下又一定没有问题?
有人说 for (int i = 0; i < 5; i++) 使用 foreach, 其实一样的。核心是for 让i这一层有效果,然后
() => Console.WriteLine(i) 让进去这一层有效果,说白此时就加大了i的生命周期,而外面的层++就改变了其值
这个行为是不是有点像是i是引用类型?那为什么这明明值类似而非引用类型呀! 这又是为何?
只能说明 这一系统定义使用的是同一个变量,而并没有函数调用参数传参的行为。
那问题 中间使用 增加一个 var temp = i ;
Console.WriteLine(i) i改为temp 又正常了呢?
这是因为 i 的作用域 已使用在了for 和 => 这两层 ,所以加深了,而增加临时变量以后 这个temp 在对for层来说 已经没有了 仅在 => 层级。
所以这就是加上临时变量就是我们想要的结果了。