在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表达式中使用循环变量的更多相关文章

  1. 关于Linq中的Lambda表达式中OrderBy的深入理解

    起因:就是一段Linq语句,OrderBy里面的i是什么? IQueryable<Student> slist = (from s in EFDB.Student select s). O ...

  2. Lambda 表达式中的变量范围

    delegate bool D(); delegate bool D2(int i); class Test { D del; D2 del2; public void TestMethod(int ...

  3. java 8 lambda表达式中的异常处理

    目录 简介 处理Unchecked Exception 处理checked Exception 总结 java 8 lambda表达式中的异常处理 简介 java 8中引入了lambda表达式,lam ...

  4. lambda表达式中无法抛出受检异常!

    抛出受检异常的时候,我们的接口应该带上throw关键字,但通过lambda表达式实现的Consumer的accept方法并不带有关键字,因此在lambda表达式中不能抛出受检异常必须把它吃掉

  5. 为什么Java中lambda表达式不能改变外部变量的值,也不能定义自己的同名的本地变量呢?

    作者:blindpirate链接:https://www.zhihu.com/question/361639494/answer/948286842来源:知乎著作权归作者所有.商业转载请联系作者获得授 ...

  6. Lambda表达式和For循环使用需要注意的一个地方

    一个需要注意的地方看下面的代码: using System; using System.Collections.Generic; using System.Linq; namespace MyCsSt ...

  7. (转) Lambda表达式中的表达式lambda和语句lambda区别

    Lambda表达式可分为表达式lambda和语句lambda 表达式lambda:表达式位于 => 运算符右侧的lambda表达式称为表达式lambda (input parameters) = ...

  8. Lambda表达式中的表达式lambda和语句lambda区别

    Lambda表达式可分为表达式lambda和语句lambda 表达式lambda:表达式位于 => 运算符右侧的lambda表达式称为表达式lambda (input parameters) = ...

  9. Javascript中的循环变量声明,到底应该放在哪儿?

    相信很多Javascript开发者都在声明循环变量时犹豫过var i到底应该放在哪里:放在不同的位置会对程序的运行产生怎样的影响?哪一种方式符合Javascript的语言规范?哪一种方式和ecma标准 ...

随机推荐

  1. cs

    cs <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.o ...

  2. zendstudio文件编码修改问题

    转载:http://blog.csdn.net/kunlong0909/article/details/7818620 朋友,在zendstudio ide中,你是否碰到导入一个项目后,发现项目中文件 ...

  3. 深入浅出设计模式——装饰模式(Decorator Pattern)

    模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制,使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是静 ...

  4. 自己动手实现STL 02:构造析构的基本工具construct()和destroy()(stl_construct.h)

    一.前言 上一篇,我先完成了对内存配置器的实现.然而后面在内存上的算法还依赖于两个全局函数,construct()和destroy(),前者负责在指定的内存上调用对象的构造函数,在内存上构造出对象.后 ...

  5. C# 将XML转换成DataSet【转】

    XmlDocument xml = new XmlDocument();xml.LoadXml(str); //str:具有xml格式的字符串 XmlNodeReader reader = new X ...

  6. mysql表结构设计

    允许NULL值的字段,数据库在进行比较操作时,会先判断其是否为NULL,非NULL时才进行值的必对.因此基于效率的考虑,所有字段均不能为空,即全部NOT NULL: 对于变长表,由于记录大小不同,在其 ...

  7. Oracle对于敏感数据的处理,可以采用策略(dbms_rls.add_policy)

    Oracle Policy的简单说明: Policy应用于数据行访问权限控制时,其作用简而言之,就是在查询数据表时,自动在查询结果上加上一个Where子句.假如该查询已有where子句,则在该Wher ...

  8. JS通过键盘点击事件实现div移动

    页面内容:文本框模拟键盘点击   div元素实现移动: <body> <textarea id="myarea"></textarea> < ...

  9. 『TensorFlow』生成式网络中的图片预处理

    简介 这里的生成式网络是广义的生成式,不仅仅指gan网络,还有风格迁移中的类自编码器网络,以及语义分割中的类自编码器网络,因为遇到次数比较多,所以简单的记录一下. 背景 1.像素和数字 图像处理目标一 ...

  10. 数据库(mysql)

    一.left join  right join  inner join left join(左连接),在两张表进行连接查询时,会返回左表所有的行,即使在右表中没有匹配的记录. right join(右 ...