在Lambda表达式中使用循环变量
在C#5.0之前,如果在foreach循环中的lambda表达式里使用循环变量,那么你会发现一些意想不到的现象,例子如下:
var integers = new List<int> { , , , };
var actions = new List<Action>();
foreach (var integer in integers)
{
actions.Add(() => Console.WriteLine(integer));
}
actions.ForEach(action => action());
这段代码的输出并不是所期望的
1
2
3
4
而是
4
4
4
4
原因是actions里的lambda表达式所捕获的循环变量被覆盖了,而循环变量的最后一个值是4. 解决方法是引入一个局部变量来让lambda表达式捕获或者使用Foreach扩展函数:
var action1s = new List<Action>();
foreach (var integer in integers)
{
var tmpInt = integer;
action1s.Add(() => Console.WriteLine(tmpInt));
}
action1s.ForEach(action => action());
var action2s = new List<Action>();
integers.ForEach(interger => action2s.Add(() => Console.WriteLine(interger)));
action2s.ForEach(action => action());
完整的例子代码和输出结果如下:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("foreach (var integer in integers)");
var integers = new List<int> { , , , };
var actions = new List<Action>();
foreach (var integer in integers)
{
actions.Add(() => Console.WriteLine(integer));
}
actions.ForEach(action => action()); Console.WriteLine("foreach (var integer in integers) with local variable");
var action1s = new List<Action>();
foreach (var integer in integers)
{
var tmpInt = integer;
action1s.Add(() => Console.WriteLine(tmpInt));
}
action1s.ForEach(action => action()); Console.WriteLine("use ForEach extension method");
var action2s = new List<Action>();
integers.ForEach(interger => action2s.Add(() => Console.WriteLine(interger)));
action2s.ForEach(action => action());
Console.WriteLine("done");
Console.Read();
}
}

在C#5.0中这个行为得到了纠正,下图是同样程序的运行结果:

在Lambda表达式中使用循环变量的更多相关文章
- 关于Linq中的Lambda表达式中OrderBy的深入理解
起因:就是一段Linq语句,OrderBy里面的i是什么? IQueryable<Student> slist = (from s in EFDB.Student select s). O ...
- Lambda 表达式中的变量范围
delegate bool D(); delegate bool D2(int i); class Test { D del; D2 del2; public void TestMethod(int ...
- java 8 lambda表达式中的异常处理
目录 简介 处理Unchecked Exception 处理checked Exception 总结 java 8 lambda表达式中的异常处理 简介 java 8中引入了lambda表达式,lam ...
- lambda表达式中无法抛出受检异常!
抛出受检异常的时候,我们的接口应该带上throw关键字,但通过lambda表达式实现的Consumer的accept方法并不带有关键字,因此在lambda表达式中不能抛出受检异常必须把它吃掉
- 为什么Java中lambda表达式不能改变外部变量的值,也不能定义自己的同名的本地变量呢?
作者:blindpirate链接:https://www.zhihu.com/question/361639494/answer/948286842来源:知乎著作权归作者所有.商业转载请联系作者获得授 ...
- Lambda表达式和For循环使用需要注意的一个地方
一个需要注意的地方看下面的代码: using System; using System.Collections.Generic; using System.Linq; namespace MyCsSt ...
- (转) Lambda表达式中的表达式lambda和语句lambda区别
Lambda表达式可分为表达式lambda和语句lambda 表达式lambda:表达式位于 => 运算符右侧的lambda表达式称为表达式lambda (input parameters) = ...
- Lambda表达式中的表达式lambda和语句lambda区别
Lambda表达式可分为表达式lambda和语句lambda 表达式lambda:表达式位于 => 运算符右侧的lambda表达式称为表达式lambda (input parameters) = ...
- Javascript中的循环变量声明,到底应该放在哪儿?
相信很多Javascript开发者都在声明循环变量时犹豫过var i到底应该放在哪里:放在不同的位置会对程序的运行产生怎样的影响?哪一种方式符合Javascript的语言规范?哪一种方式和ecma标准 ...
随机推荐
- www
dddd int vec_rotate(char *vec,int rotdist, int length) { int i,j,k,times; char t; times = gcd(rotdis ...
- JS小数位保留两位小数--toFixed()
parseInt,parseFloat,parseDouble在JS中是将值转换成相应的类型: 你必须要这样,才能实现: <script> alert(parseFloat ...
- PHP 中数组函数 isset 效率比 array_key_exists 更高
PHP 中数组函数 isset 效率比 array_key_exists 更高 PHP 浏览:4194 2014年04月05日 isset 和 array_key_exists 函数都可以用来测试数组 ...
- Android再学习-20141018-布局-进度条
20141018-Android再学习 对齐至控件的基准线 为了保证印刷字母的整齐而划定的线(四线三格的第三条线). android:layout_alignBaseline 与父控件的四个边缘对齐( ...
- docker --- 初识
Docker简介 Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机).ba ...
- 添加AdMob 错误记录
依照官方教程添加文件及其 frameWork后 发现运行报错 错误如下 Undefined symbols for architecture i386: "_OBJC_CLASS_$_ASI ...
- 免费馅饼(HDU 1176 DP)
免费馅饼 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- 观《Terminal》之感
读书笔记系列链接地址http://www.cnblogs.com/shoufengwei/p/5714661.html. 经人推荐,用了几天时间欣赏了这部斯皮尔伯格导演的电影<Te ...
- [LA] 3644 - X-Plosives [并查集]
A secret service developed a new kind of explosive that attain its volatile property only when a spe ...
- 在Android模拟器中经常出现以下错误 timeout Launch canceled!
Failed to install MainActivity.apk on device 'emulator-5554': timeoutLaunch canceled! 解决方法: window-& ...