16.1 foreach 循环中捕获变量的变化
在 foreach 循环内的匿名函数(通常为Lambda表达式)中捕获循环 变量时要格外小心。代码清单16-1就展示了这样一个简单的示例,它看上去似乎会输出 x 、 y 、 z 。
string[] values = new string[] { "x", "y", "z" };
var actions = new List<Action>();
foreach (string value in values)
{
actions.Add(() => Console.WriteLine(value));
}
foreach (Action action in actions)
{
action();
}
在C# 3和C# 4中,以上代码实际上会打印出三个 z 。循环变量( value )可由Lambda表达式捕获,且名义上在循环的每次迭代中,只有一个变量“实例”的值发生了变化。全部三个委托都将引用相同的变量,并且在最终执行时,该变量的值为 z 。这并不是编译器实现上的错误,而是语言被指定所产生的行为。
在C# 5中,语言的行为与当初预期的一样:循环的每次迭代都可有效地引入一个单独变量。 每个委托都引用不同的变量,变量的值就是这次循环迭代中产生的值。
有关该特性的内容就讲到这里,它只是修复了会让很多开发者产生疑惑的语言部分而已。 (Stack Overflow上有超多人询问这方面的问题。)
但此处要提醒一句:如果编写的代码需用不同版本的C#编译器进行编译,则应注意它们产生 的行为是不同的。对于任何版本的C#来说,代码清单16-1都不会产生警告,而在C# 5中,行为却 神不知鬼不觉地发生了改变。要慎之又慎,并且确保有单元测试可以依靠。
16.1 foreach 循环中捕获变量的变化的更多相关文章
- js for 循环中的 变量问题。
今日处理项目中的一个循环,本来就是一个小小的for循环,后来发现该段程序出现了问题,仔细检查代码没有发现其中的错误.无奈只好叫来了老大帮忙.通过在模版中断点调试(该方式只能自己写debugger断点) ...
- C#在foreach循环中修改字典等集合出错的处理
C#在foreach循环中修改字典等集合出错:System.InvalidOperationException: Collection was modified; enumeration operat ...
- 【SQL】小心在循环中声明变量——浅析SQL变量作用域
本文适用:T-SQL(SQL Server) 先看这个语句: --跑3圈 BEGIN --每圈都定义一个表变量,并插入一行 DECLARE @t TABLE(Col INT PRIMARY KEY) ...
- C#不允许在foreach循环中改变数组或集合中元素的值(注:成员的值不受影响)
C#不允许在foreach循环中改变数组或集合中元素的值(注:成员的值不受影响),如以下代码将无法通过编译. foreach (int x in myArray) { x++; //错误代码,因为改变 ...
- 「译」forEach循环中你不知道的3件事
前言 本文925字,阅读大约需要7分钟. 总括: forEach循环中你不知道的3件事. 原文地址:3 things you didn't know about the forEach loop in ...
- 【PHP】 foreach循环中变量引用的一道面试题
$a = array('a','b','c'); foreach($a as &$v){} foreach($a as $v){ } var_dump($a); 现在.不要打开浏览器,猜测一下 ...
- 关于“foreach循环”中遇到的几个问题总结
1.列表页面用"foreach循环"的时候数据没有显示,此时需要检查你对象模型中属性的首字母是否大写,切记不能大写(本人在做一个项目的时候,对象模型是别人建立的,属性首字母大写了, ...
- 用闭包解决 js 循环中函数变量暂存问题
需求:有一个数组,根据数组的值渲染对应的数字div,单击对应的div 在控制台打印对应的数字.如点击1,控制台打印1. 问题: 不管点击哪个值 打出来都是4 代码如下 <!DOCTYPE htm ...
- foreach循环中为什么不要进行remove/add操作
先来看一段代码,摘自阿里巴巴的java开发手册 List<String> a = new ArrayList<String>(); a.add("1"); ...
随机推荐
- View载入具体解释
文章一開始我要对前面一篇文章做点补充 相信大家都知道View有两个方法. public boolean post(Runnable action) public boolean postDelayed ...
- Ubuntu 12.04 LTS 无法进入桌面环境
今天开机后,在登陆的时候,进入了登陆界面(选择用户,输入密码的那个界面),输入正确的密码后屏幕跳转了一下,但是很快又回到了登陆界面.然后我就尝试以guest [访客]的身份登陆,发现进入了桌面系统. ...
- .NET平台下Redis使用(三)【ServiceStack.Redis学习】
MVC4项目下对redis进行增删该查 Models文件下实体类: public class Book { public string BookName {get;set;} public strin ...
- bzoj1227
离散化+树状数组+排列组合 很久以前就看到过这道题,现在依然不会做...看完题解发现思路很简单,就是有点难写 我们先将坐标离散化,x和y最大是w,然后我们就有了一个暴力做法, 枚举每块墓地,统计,因为 ...
- 56. EditorGridPanel和渲染器renderer的使用
转自:https://blog.csdn.net/chenkangwan/article/details/4748716?utm_source=blogxgwz6 1. 在EditorGriddPan ...
- 使用 Jenkins + GitHub + Nginx + HTTPS 搭建静态网站
参考https://www.imooc.com/article/20079 http://www.haoduoyu.cc/
- E20170630-ts
displacement n. 取代,替代; 免职,停职; [船] 排水量; [化] 置换;
- js产生随机数教程
<script> function GetRandomNum(Min,Max){ var Range = Max - Min; var Rand = Math.random() ...
- JQuery 总结
JQuery官方网站 http://jquery.com/ 1.JQuery概念 A.Jquery是一个优秀的Javascript框架.它是轻量级的js库 ,它兼容CSS3,还兼容各种浏览器,jQu ...
- 基于Spark Streaming预测股票走势的例子(二)
上一篇博客中,已经对股票预测的例子做了简单的讲解,下面对其中的几个关键的技术点再作一些总结. 1.updateStateByKey 由于在1.6版本中有一个替代函数,据说效率比较高,所以作者就顺便研究 ...