在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语言生产随机数的方法
尽管在计算机中并没有一个真正的随机数发生器,但是可以做到使产生的数字的重复率很低,以至于它们看起来是随机的.实现这一功能的程序叫做伪随机数发生器. 有关如何产生随机数的理论有许多,这里不讨论这些理论及 ...
- Java BufferedWriter与BufferedReader操作文本文件
/** * 采用字符流读取写入文本文件 */ public class FileUtil { /** * 写文件 * @param fileName * @param content */ publi ...
- linux find详解
find是最常见和最强大的查找命令,你可以用它找到任何你想找的文件. find的使用格式如下: $ find <指定目录> <指定条件> <指定动作> - < ...
- 使用 Strace 和 GDB 调试工具的乐趣
编写 UNIX® 系统程序充满乐趣,并且具有教育意义.使用 UNIX strace 工具和 GDB(GNU 项目调试工具),您可以真正地深入研究系统的功能,并了解组成这些功能的各种各样的程序.同时使用 ...
- jquery datepicker日期控件用法
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.c ...
- Android使用bindService启动服务
1.Service package com.example.ebobo; import java.util.Timer; import java.util.TimerTask; import andr ...
- 新建一个MVCProject 项目
App_Data文件夹用于存放数据库文件的 App_Start文件夹用于存放Web应用程序启动时需要进行重要配置的类文件 Content 文件夹用于存放主题样式文件 Controllers 文件夹用于 ...
- feof()
百度知道 >电脑/网络 >编程语言 >C/C++ feof()这个函数是用来判断指针是否已经到达文件尾部的. 若fp已经指向文件末尾,则feof(fp)函数值为"真&quo ...
- 表单验证插件jquery.validate的使用方法演示
jQueryValidate表单验证效果 jquery.validate验证错误信息的样式控制 <!--validate验证插件的基础样式--> input.error{border: 1 ...
- Block 代替for循环
NSDictionary *aDictionary = [[NSDictionary alloc]initWithObjectsAndKeys:", nil]; [aDictionary e ...