for循环委托捕获值永远为最终值

转自 https://www.xuebuyuan.com/130945.html
发现程序的一个BUG究其原因是因为在for循环中用委托捕获了声明变量(就是那个常见的变量i),这种情况会发生在当你捕获了for循环的声明变量,但是在声明变量已经改变后才去调用委托,你期望得到捕获变量时的值,但是得到的会是变量最终的值,即便变量类型是值类型。来看这段代码:

var list = new Action[5];

for (int i = 0; i < 5; i++)

{

    list[i] = new Action(() => Console.WriteLine(i));

}

 

foreach (var a in list)

    a();

显然我期望每一个Action中捕获的是当时的值,但是输出会是:

5

5

5

5

5

for中的生命变量其实就是一个局部的全局变量,就类似这样:

int i = 0;

for (; i < 5; i++)

{ /* ... */ }

解决方案就是不用这个for循环的声明变量,可以随便声明一个局部临时变量来保存当前值:

for (; i < 5; i++)

{

    var local = i;

    list[i] = new Action(() => Console.WriteLine(local));

}

这样不不会输出5个5了。

当然用List.ForEach就不会出现这种问题,代码:

var list = new Action[5];

Enumerable.Range(0, 5).ToList().ForEach(i =>

{

    list[i] = new Action(() => Console.WriteLine(i));

});

 

foreach (var a in list)

    a();

输出:

0

1

2

3

4
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值