在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标准 ...
随机推荐
- C# 操作NPOI导入导出
//把T_Seats中的输入导出到Excel private void button3_Click(object sender, EventArgs e) { //1.读取 string sql = ...
- POJ - 2653 - Pick-up sticks 线段与线段相交
判断线段与线段相交 莫名其妙的数据量 #include <iostream> #include <cstdio> #include <vector> #includ ...
- nyoj 最少步数
算法:搜索(深度优先搜索) 描述 这有一个迷宫,有0~8行和0~8列: 1,1,1,1,1,1,1,1,1 1,0,0,1,0,0,1,0,1 1,0,0,1,1,0,0,0,1 1,0,1,0,1, ...
- javascript-几个基础的排序算法
对这几个基础排序算法进行梳理,便于以后查看. /** * * 冒泡排序 * 从末尾开始相邻两数相互比较大小,满足条件就交换位置.循环每进行一次,即可确定第i位数的值. *冒泡排序的时间复杂度为O(n^ ...
- POJ1459 最大网络流
问题: POJ1459 涉及内容:最大网络流 分析: 本题问题看似非常复杂,实际上可以转化为单源点单汇点的最大网络流问题. 1)因为电量只在发电站产生,故增加源点S,构建从S到每个发电站的有向边,边的 ...
- Taum and B'day
//自己 def main(): t = int(raw_input()) for _ in range(t): units = 0 b, w = map(int, raw_input().strip ...
- Hdu1091
#include <stdio.h> int main() { int a,b; while(scanf("%d %d",&a,&b)){ && ...
- easyui 添加dialog
javascript //查看角色所属用户 function roleuser(obj, id) { var C_ID = id; var Url = "/Sys/RoleUserName& ...
- Linux(Centos)下安装MySQL
转载:http://www.cnblogs.com/xiaoluo501395377/archive/2013/04/07/3003278.html 一.mysql简介 说到数据库,我们大多想到的是关 ...
- Hibernate整合Struts2时报错
今天在整合Hibernate和Struts2的时候遇到一个问题 总是出现各种异常,经过仔细检查,代码本身并没有问题, ----------------------------------------- ...