NET也有闭包
NET也有闭包
在.NET中,函数并不是第一级成员,所以并不能像JavaScript那样通过在函数中内嵌子函数的方式实现闭包,通常而言,形成闭包有一些值得总结的非必要条件:
嵌套定义的函数。
匿名函数。
将函数作为参数或者返回值。
在.NET中,可以通过匿名委托形成闭包:
delegate void MessageDelegate();
static void Main(string[] args)
{
string value = "Hello, Closure.";
MessageDelegate message = delegate()
{
Show(value);
};
message();
}
private static void Show(string message)
{
Console.WriteLine(message);
}
事实上,大部分支持闭包的高级语言中,函数都是第一级成员,函数可以作为参数传递,也可以作为返回值返回,或者作为函数变量。而在.NET中,这一切都可以通过委托来实现,关于委托的详情请参考9.7节“一脉相承:委托、匿名方法和Lambda表达式”,所以上述逻辑也可以通过Lambda表达式实现更简单的代码。
反编译上述示例为IL代码:
.class private auto ansi beforefieldinit Program
extends [mscorlib]System.Object
{
.method private hidebysig static void Main(string[] args) cil managed
{
// 省略
}
.class auto ansi sealed nested private beforefieldinit <>c__DisplayClass1
extends [mscorlib]System.Object
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGenerated Attribute::.ctor()
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
// 省略
}
.method public hidebysig instance void <Main>b__0() cil managed
{
// 省略
}
.field public string value
}
}
通过匿名方法将自动形成闭包,自由变量value被包装在一个内部类(闭包)中,并升级为实例成员,即使创建该变量的方法执行结束,该变量也不会释放,而是在所有回调函数执行之后才被GC回收。自由变量value的生命周期被延长,并不局限为一个局部变量。生命周期的延迟,是闭包带来的福利,但是也往往带来潜在的问题,造成更多的消耗。
1.闭包与函数
像对象一样的操作函数,是闭包发挥的最大作用,从而实现了模块化的编程方式。不过,闭包与函数并不是一回事儿。
闭包是函数与其引用环境组合而成的实体。不同的引用环境和相同的函数可以组合产生不同的闭包实例。
函数是一段可执行的代码体,在运行时不会由于上下文环境发生变化。
2.应用闭包
闭包,是函数式编程的精灵,在.NET平台中,这个精灵同样带来诸多方面的应用,典型的表现主要体现在以下几方面。
定义控制结构,实现模块化应用。闭包实现了以最简单的方式开发粒度最小的模块应用,实现一定程度的算法复用,下例的ForEach为遍历数组元素提供了复用基础,对于加法运算和减法运算而言,在闭包中改变引用环境变量的值,达到最小粒度的模块控制效果。
static void Main()
{
int[] values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int result1 = 0;
int result2 = 100;
values.ForEach(x => result1 += x);
values.ForEach(x => result2 -= x);
Console.WriteLine(result1);
Console.WriteLine(result2);
}
多个函数共享相同的上下文环境,进而实现通过上下文变量达到数据交流的作用。
static void Main()
{
int value = 100;
IList<Func<int>> funcs = new List<Func<int>>();
funcs.Add(() => value + 1);
funcs.Add(() => value - 2);
foreach (var f in funcs)
{
value = f();
Console.WriteLine(value);
}
}
数据共享为不同函数的操作间传递数据带来方便,但是这把双刃剑有时又为不需要共享数据的场合带来问题,以上例而言,value变量将在不同的操作中() => value + 1和() => value – 2间共享数据。如果不希望在两次操作间传递数据,需要特别注意引入中间量协调:
static void Main()
{
int value = 100;
IList<Func<int>> funcs = new List<Func<int>>();
funcs.Add(() => value + 1);
funcs.Add(() => value - 2);
foreach (var f in funcs)
{
int v = f();
Console.WriteLine(v);
}
}
本文节选自《你必须知道的.NET(第2版)》一书
图书详细信息:http://bvbroadview.blog.51cto.com/3227029/635423
转载于:https://blog.51cto.com/bvbroadview/635435
相关文章:

【opencv】ubuntu14.04上编译opencv2.4
参考博客 https://blog.csdn.net/c406495762/article/details/62896035 1、安装依赖库 sudo apt-get install build-essential cmake libgtk2.0-dev pkg-config python-dev python-numpy libavcodec-dev libavformat-dev libswscale-dev sudo apt-get install libv4l-0 libv…

1024块TPU在燃烧!BERT训练从3天缩短到76分钟 | 技术头条
点击上方↑↑↑蓝字关注我们~「2019 Python开发者日」全日程揭晓,请扫码咨询 ↑↑↑作者 | 琥珀出品 | AI科技大本营(ID:rgznai100)“Jeff Dean称赞,TensorFlow官方推特支持,BERT目前工业界最耗时的应用,计…

牵引力教育设计总监解密9大2018潮流UI设计趋向
作为一名紧跟时代潮流的UI设计师,设计的风格一定要紧跟上最新的设计趋势,因为更为有效且颇具趣味的响应式图标必将得到关注。同时,鲜艳丰富的色彩,精彩纷呈的插图设计都会博得用户眼球。这样你的设计更容易获得更多人的认可与热爱…

Android媒体相关开发应用程序接口
翻译自:http://developer.android.com/guide/topics/media/index.html MediaAndroid框架支持各种普通media类型的编解码,因此你可以很容易地把音频,视频和图片整合到你的应用程序中。通过使用MediaPlayer的接口,你可以播放各种音视…

Facebook开源图嵌入“神器”:无需GPU,高效处理数十亿级实体图形 | 极客头条...
点击上方↑↑↑蓝字关注我们~「2019 Python开发者日」全日程揭晓,请扫码咨询 ↑↑↑编译 | Major、一一出品 | AI科技大本营(ID: rgznai100)有效处理大规模图对于促进人工智能的研究和应用至关重要,但特别是在工业应用中的图&…

【opencv】ubuntu14.04上编译opencv-4.0.1 + opencv_contrib-4.0.1
1、要求 编译器版本:c11 cmake版本:3.5.1 2、安装camke 2.1 官网下载:https://cmake.org/download/ 选择:Linux x86_64 cmake-3.14.1-Linux-x86_64.sh 2.2 安装: 将cmake-3.14.1-Linux-x86_64.sh拷贝考ubuntu中&…

软件开发文档模板 (学习)
1 可行性研究报告 可行性研究报告的编写目的是:说明该软件开发项目的实现在技术、经济和社会条件方面的可行性;评述为了合理地达到开发目标而可能先择的各种方案;说明论证所选定的方案。 可行性研究报告的编写内容要求如下: …

Unix数据中心主宠儿
曾几何时UNIX一直是除个人电脑之外的领域中应用最为广泛的操作系统,并且为现代操作系统的成型奠定了基础,可以说UNIX的历史就像应用程序本身一样耐人寻味。UNIX的过去回首1983年,肯.托马森和D.里奇由于对操作系统发展史以及UNIX操作系统应用所…

【AI】基本概念
1、什么是人工智能 人工智能(AI)是通过研究、开发,来找到用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的综合性的科学技术。其表现为,让计算机系统通过机器学习等方式,来获得可以履行原本只有依…

在浏览器中进行深度学习:TensorFlow.js (四)用基本模型对MNIST数据进行识别
2019独角兽企业重金招聘Python工程师标准>>> 在了解了TensorflowJS的一些基本模型的后,大家会问,这究竟有什么用呢?我们就用深度学习中被广泛使用的MINST数据集来进行一下手写识别的操作。 MINST数据集 MINST是一组0到9的手写数字…

不止临床应用,AI还要帮不懂编程的医生搞科研
近日,推想科技发布 AI 学者科研平台 InferScholar Center,该平台为更多的医生提供零门槛的 AI 科研能力,让医生可以快速将深度学习、影像组学以及文本数据处理相关的前沿技术应用到自己的临床科研实践中,他们将为平台上的医疗科研…

rhel6Inode详解
在Linux文件系统中,很多人对Inode都不太明白,今天我就和大家一起来分享一下我对Inode的认识,如果有理解错误的地方,请大家多多批评指点。在上一篇一天一点学习Linux之认识文件系统中,在最后给出了一张EXT3文件系统结构…

争论不休的TF 2.0与PyTorch,到底现在战局如何了? | 技术头条
点击上方↑↑↑蓝字关注我们~「2019 Python开发者日」全日程揭晓,请扫码咨询 ↑↑↑作者 | Jeff Hale译者 | Jackey编辑 | Jane出品 | AI科技大本营(id:rgznai100)【导语】 TensorFlow 2.0 和 PyTorch 1.0 陆续发布后,…

struts2实验2:struts2.xml action中* ,{}以及${}
p.s 关键在于struts.xml中的匹配,使用* ,{}以及${}可以让代码更加简洁清晰 代码核心思路 在struts.xml中通过路由(url)去指定控制逻辑的Action中的方法,例如 <package name"admin" namespace"/admin" extends"struts-global">&…

【Ubuntu】dpkg-deb -c :查看deb文件中的内容
1、dpkg-deb -c :查看deb文件中的内容 $ dpkg-deb -c packageeg: $ dpkg-deb -c sogoupinyin_2.2.0.0108_amd64.deb drwxr-xr-x root/root 0 2018-04-18 16:50 ./ drwxr-xr-x root/root 0 2018-04-18 16:50 ./etc/ drwxr-xr-x root/root …

捕获Camera并保存图片到本地(照相功能) -samhy
Flex博文 捕获Camera并保存图片到本地(照相功能) -samhy作者:admin 日期:2010-07-12字体大小: 小 中 大捕获Camera并保存图片到本地(照相功能)这几天对Camera类进行了一下规整,并利用JPGEncoder类实现了照相的功能,代码如下: XML/HTML代码import flash.m…

【C++】模板函数的声明和定义必须在同一个文件中
1、问题描述 习惯性的将函数的定义和实现,分别写在头文件和源文件(.cpp)中。今天也按照这个习惯实现了一个模板函数。然后编译时报错 ... error: undefined reference to ...2、原因分析 c中模板的声明和定义不能分开。C中每一个对象所占用…

基于AWS-ELK部署系统日志告警系统
前言 运维故障排障速度往往与监控系统体系颗粒度成正比,监控到位才能快速排障 在部署这套系统之前,平台所有系统日志都由GraylogZabbix,针对日志出现的错误关键字进行告警,这种做法在运维工作开展过程中暴露出多个不足点ÿ…

《周志华机器学习详细公式推导版》发布,Datawhale开源项目pumpkin-book
点击上方↑↑↑蓝字关注我们~「2019 Python开发者日」全日程揭晓,请扫码咨询 ↑↑↑来源 | Datawhale(ID:Datawhale) 如果让你推荐两本国内机器学习的入门经典作,你会推荐哪些呢?相信大家同我一样ÿ…

JVM内存泄漏检测与处理
JVM内存泄漏检测与处理(JVM Memory Leak detection and handling) JVM垃圾回收机制的原则和方法 JVM垃圾回收中一个基本原则是对象没有被引用或则引用其它对象,换句话说当一个对象在heap 中是隔离(isolation)状态的时候,垃圾回收器…

【Dlib】dlib和opencv的互转
一、dlib::matrix转换成cv::Mat 1、注意事项: 1)将dlib::matrix转成BGR格式后,再转换成cv::Mat,因为cv::Mat中是按照BGR顺序存储 2)注意最后添加的cv::Mat::clone()函数,因为dlib::toMat(tmp)返回的mat数…

原创 人物志|山东省临沭县 - 一位身残志坚的奋斗青年 - 吴忠军
原创 人物志|山东省临沭县 - 一位身残志坚的奋斗青年 - 吴忠军 02972018-04-29 16:15:27 人物志|山东省临沭县 - 一位身残志坚的奋斗青年 - 吴忠军 齐鲁晚报 2018年04月29日 2018年4月29日,山东省临沂市临沭县,一位年轻的小伙子。吴忠军,山东…

百度SLG拿下前锤子科技CTO钱晨,还要合并小鱼在家? | 极客头条
点击上方↑↑↑蓝字关注我们~「2019 Python开发者日」全日程揭晓,请扫码咨询 ↑↑↑整理 | 一一出品 | AI科技大本营(id:rgznai100)2016 年 7 月,锤子科技前 CTO 钱晨从该公司退休的消息被证实,关于其离职的…

【Dlib】dlib实现深度网络学习之 input层
1、 dlib::input 模板类,深度神经网络的简单输入层,它将某种图像作为输入并将其加载到网络中。 这是一个基本的输入层,它只是简单地将图像复制到一个张量中。 注意:dlib::input只支持输入dlib::matrix和dlib::array2d类型&#x…

首发 | 13篇京东CVPR 2019论文!你值得一读~ 技术头条
点击上方↑↑↑蓝字关注我们~「2019 Python开发者日」全日程揭晓,请扫码咨询 ↑↑↑编者按:计算机视觉和模式识别大会 CVPR(Conference on Computer Vision and Pattern Recognition)作为人工智能领域计算机视觉方向的重要学术会议…

Windows 活动目录(AD)服务器系统升级到2012之活动目录角色迁移(三)
4.5迁移服务器角色到AD20121. 打开powershell,使用命令迁移服务器角色到AD2008输入命令Ntdsutil输入命令Roles输入命令Connections输入命令Connect to server AD2012,连接AD2012控制器输入命令QUIT输入Transfer infrastructure master命令,转…

《星际争霸2》引擎技术解析
就在SIGGRAPH大会刚结束之后,AMD和暴雪在AMD官方网站上放出了《星际争霸II》的官方技术文档,通过游戏引擎技术的展示让星际迷们感受到越来越多的惊喜。画面优化给CPU带来考验着色方面,在使用原型的基础上利用3D Studio MAX让程序员对整体效果…

回顾与展望:大热的AutoML究竟是什么? | 技术头条
点击上方↑↑↑蓝字关注我们~「2019 Python开发者日」全日程揭晓,请扫码咨询 ↑↑↑来源 | 第四范式编者按:AutoML(Automatic Machine Learning,自动机器学习)旨在研究在没有专业知识的情况下使用的低门槛甚至零门槛的…

【Python】深度学习中将数据按比例随机分成随机 训练集 和 测试集的python脚本
深度学习中经常将数据分成 训练集 和 测试集,参考博客,修改python脚本 randPickAITrainTestData.py 。 功能:从 输入目录 中随机检出一定比例的文件或目录,移动到保存 测试集目录 中,原输入目录作为训练目录。 import…

docker 系列之 配置阿里云镜像加速器
1.登录阿里云 2.登录后找到右上角的“管理中心”,点击进入后》点击“镜像加速器”;剩下的安装文档配置就好 问题1:配置完后还是提示:Tag latest not found in repository 【本人也是在这里被困了好久,尝试了各种方法】 解决方案:最后发现这里…