关于Lambda表达式访问外部变量
在《C#高级编程》一书中提到通过Lambda表达式可以访问Lambda表达式块外部的变量 ,这是一个很好的功能(类似Js中的 闭包)。但是如果没有正确的使用,会非常危险。
比如下面的事例中
int someVal = 5;
Fun<int, int> f = x => x + someVal;
Console.WriteLine(f(3));
我们这个表达式的本意是返回一个数x+5的结果。所以f(3)的结果应该是 3 + someVal = 8。
但是如果以后在不经意中修改了someVal的值,则会出现我们意想不到的结果。
比如:
someVal = 7;
Console.WriteLine(f(3));
此时的打印的结果是10。
特别是当通过多个线程调用Lambda时,我们可能不知道此时someVal的值到底是多少,从而导致不可预知的结果,所以要慎重使用。
那么,在Lambda表达式中使用外部变量的原理是什么呢。
原来,在运行Lambda表达式时,编译器会创建一个匿名类,他可以通过构造函数来传递外部变量。该构造函数的参数取决于外部传递进来的变量个数。对于上面的表达式,匿名类如下所示:
public class AnonymousClass {
private int someVal;
public AnonymousClass(int someVal) { this.someVal = someVal; }
public int Anonymous(int x) { return x + someVal; }
}
这样就可以理解为什么Lambda表达式可以使用外部变量了。
关于Lambda表达式访问外部变量的更多相关文章
- 让boost.variant支持lambda表达式访问
前言 之前写个过一篇博客叫<浅谈boost.variant的几种访问方式>,里面讲到了可以通过访问者方式来获取variant的值,但是在重载函数operator()里面只能够获取varia ...
- ios中block访问外部变量的一些注意点
Block类型是一个C级别的语法和运行机制.它与标准的C函数类似,不同之处在于,它除了有可执行代码以外,它还包含了与堆.栈内存绑定的变量.因此,Block对象包含着一组状态数据,这些数据在程序执行时用 ...
- C++ lambda 表达式传递的变量默认不可变
我遇到例如以下问题: int count=0; listener->onTouchMoved=[count](Touch* t,Event* e){ count++; log("onT ...
- JavaScript中子函数访问外部变量的方法
我们在写web页面时,肯定会经常遇到下面这种情况: <body> <div class="btns-wrapper"></div> <sc ...
- Java8初体验(一)lambda表达式语法
感谢同事[天锦]的投稿.投稿请联系 tengfei@ifeve.com 本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人也是刚刚开始学习Java8,所以文中肯定有错误和理解 ...
- Java8特性详解 lambda表达式 Stream
1.lambda表达式 Java8最值得学习的特性就是Lambda表达式和Stream API,如果有python或者javascript的语言基础,对理解Lambda表达式有很大帮助,因为Java正 ...
- Java8学习笔记----Lambda表达式 (转)
Java8学习笔记----Lambda表达式 天锦 2014-03-24 16:43:30 发表于:ATA之家 本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人 ...
- lambda表达式2
1.lambda表达式 Java8最值得学习的特性就是Lambda表达式和Stream API,如果有python或者javascript的语言基础,对理解Lambda表达式有很大帮助,因为Java正 ...
- Java8之lambda表达式
一.什么是lambda表达式? Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码 ...
随机推荐
- Spring、Hello AOP
AOP 概念:http://blog.csdn.net/moreevan/article/details/11977115 AOP 所使用到的jar 包: aspectjrt.jar common-a ...
- git push报错
git: No refs in common and none specified; doing no (2012-10-28 11:43:10) 转载▼ 标签: 杂谈 分类: 项目管理 用gitol ...
- Android消息推送的服务端
2.Android消息推送 MQTT服务器采用mosquito http://mosquitto.org/ PHP管理包采用phpmqttclient:https://github.com/toku ...
- Android不规则瀑布流照片墙的实现+LruCache算法
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZnJhbmNpc3NoaQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- Java可视化编程,基于布局管理器的UI设计
在<事件驱动模型>讲述了如何将用户与功能实现代码联系到一起.怎么样便于用户理解和符合用户的使用习惯? 本篇还是就此问题作分析,站在用户角度上分析UI各组件倒底该如何设计呈现. 优秀的UI会 ...
- 怎样解决Ubuntu发热严重地问题
刚装ubuntu的时候那是相当地热,hot.直接地原因是没有对应地显卡驱动,然后在software update里面找到Nivida地最新驱动,兴高採烈地装上试一试.一点用处没有! 在网上搜了搜,有一 ...
- A Guide to the Multiboot Process
A Guide to the Multiboot Process The XP and Vista boot process in general.The Windows dual and multi ...
- 前端新人学习笔记-------html/css/js基础知识点(三)
这断时间家里有点事,上班也有点任务,所以几天没看视频没来更新了.今天来更新一下了. 一:默认样式重置 但凡是浏览默认的样式,都不要使用. body,p,h1,h2,h3,h4,h5,h6,dl,dd{ ...
- spring加载jar包中多个配置文件
转自:http://www.cnblogs.com/GarfieldTom/p/3723915.html <import resource="classpath*:applicatio ...
- 在 PL/SQL Developer 中执行SQL文件的方法
打开 command Window SQL> @'D:\My Documents\Downloads\bde_chk_cbo.sql'; 整个路径及文件两边要有单引号哦!