随便聊聊Lambda

69 篇文章 6 订阅

C#用多了,对于Lambda肯定不陌生,作为创建委托的一种简易方式,使用上确实相当顺手,不过用的多了,难免也会踩坑,下面这个坑可能就有不少朋友踩过:

var count = 8;
var Func = new List<Action>(count);

for (int i = 0; i < count; ++i)
{
    Func.Add(() => { Console.WriteLine(i); });
}

foreach (var action in Func)
{
    action();
}

代码很简单,使用List缓存了一些委托然后执行,那么执行的结果是什么呢?一些朋友可能会脱口而出: 0 1 2 3 4 5 6 7
可惜正确答案却是: 8 8 8 8 8 8 8 8 ! 原因在于Lambda表达式中捕获的i是同一个引用变量!

代码改成这样也许会更清晰一些(这里i被写在了循环外):

var count = 8;
var Func = new List<Action>(count);

int i = 0;
for (i = 0; i < count; ++i)
{
    Func.Add(() => { Console.WriteLine(i); });
}

foreach (var action in Func)
{
    action();
}

为了避免这个问题,我们需要创建不同的局部变量(这里我们通过创建多份index来缓存中间数值):

var count = 8;
var Func = new List<Action>(count);

for (int i = 0; i < count; ++i)
{
    int index = i;
    Func.Add(() => { Console.WriteLine(index); });
}

foreach (var action in Func)
{
    action();
}

实际上这个坑在C#5之后就被填上了,只是现实来看,你可能还没法用上C#5(例如Unity目前仍不支持),所以在平时使用Lambda时还是要多留下心~

OK,闲聊结束,下次再见吧~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值