[2018年最新整理]C#与闭包详解.docVIP

  1. 1、本文档共12页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
[2018年最新整理]C#与闭包详解

C#与闭包   首先想说明一点,虽然有这样那样的不好的心态(比如中文技术书),但总体来说,国内的技术人员还是喜欢分享和教导别人的,这点我的个人感受和之前在园子里看到的朋友的感受恰恰相反。个人认为其实国内很多技术网友都是很热心的,可能因为语言问题同一个技术热点会稍稍落后国外一些,但一些成熟的或者基础的概念都可以找到很细致的中文介绍,特别是关于闭包。因为它的字面解释确实很绕,所以基本所有试图解释这一名词的同学都是尽量用自己认为最通俗易懂的方式来进行讲解。闲话扯远了,这里我就用C#语言来给大家解释下闭包吧。   其实要提到闭包,我们还得先提下变量作用域和变量的生命周期。   在C#里面,变量作用域有三种,一种是属于类的,我们常称之为field;第二种则属于函数的,我们通常称之为局部变量;还有一种,其实也是属于函数的,不过它的作用范围更小,它只属于函数局部的代码片段,这种同样称之为局部变量。这三种变量的生命周期基本都可以用一句话来说明,每个变量都属于它所寄存的对象,即变量随着其寄存对象生而生和消亡。对应三种作用域我们可以这样说,类里面的变量是随着类的实例化而生,同时伴随着类对象的资源回收而消亡(当然这里不包括非实例化的static和const对象)。而函数(或代码片段)的变量也随着函数(或代码片段)调用开始而生,伴随函数(或代码片段)调用结束而自动由GC释放,它内部变量生命周期满足先进后出的特性。   那么这里有没有例外呢?   答案是有的,不过在提这点之前,我还需要给各位另外一个名词。都说C#就是MS版本的Java,这话在.NET 1.0可能可以这么说,但自2.0之后C#就可以自豪的说它绝非java了,这里面委托有很大的功劳。如果用过Java和C#的人并且尝试过写WinForm程序时全部手写实现代码的人就会有这样一个感受,同样的click事件,在Java中必须要无端的套个匿名类,但在c#中,你是可以直接将函数名+=到事件之后而不需要显示写上匿名委托的对象类型的。因为编译器会帮你做这部分工作,在3.0和以后的版本之中,微软将委托的用法更是发挥的淋漓精致,无论是简洁的Lamda还是通俗易懂的LINQ,都是源自委托的。   你可能要问,委托和我们今天要讲的闭包又有什么关系呢?   我们知道,C#, Java和JavaScript, Ruby, Python这些语言不同,在C#和Java的世界里面,原子对象就是类(当然还有struct和基本变量),而不是很多动态语言中的函数,我们可以实例化一个类,实例化一个变量,但不可以直接new 一个函数。也就是表面上看,我们是没办法像js那样将函数进行实例化和传递的。这也是为什么直到Java 7闭包才被姗姗来迟的加入Java特性中。但对C#来说这些只是表象,我刚学C#的时候,看到最多的解释委托的话就是:委托啊,就相当于C++里面的函数指针啦。这句话虽然笼统,但确实有一定道理,通过委托特别是匿名委托这层对象的包装,我们就可以突破无法将函数当做对象传递的限制了。   好像这里还是没讲到闭包和委托的关系,好吧,我太啰嗦了,下面从概念开始讲。   闭包其实就是使用的变量已经脱离其作用域,却由于和作用域存在上下文关系,从而可以在当前环境中继续使用其上文环境中所定义的一种函数对象。   好拗口,程序员,还是用示例来说明更好理解。   首先来个最简单的JavaScript中常常见到的关于闭包的例子: function f1(){   var n = 999;   return function(){     alert(n); // 999 return n;   } } var a = f1(); alert(a());   这段代码翻译成C#代码就是这样: public class TCloser { public Funcint T1() { var n = 999; return () = { Console.WriteLine(n); return n; }; } } class Program { static void Main() { var a = new TCloser(); var b = a.T1(); Console.WriteLine(b()); } }   从上面的代码我们不难看到,变量n实际上是属于函数T1的局部变量,它本来生命周期应该是伴随着函数T1的调用结束而被释放掉的,但这里我们却在返回的委托b中仍然能调用它,这里正是闭包所展示出来的威力。因为T1调用返

文档评论(0)

liwenhua00 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档