博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c#中闭包的实现方法
阅读量:6567 次
发布时间:2019-06-24

本文共 1999 字,大约阅读时间需要 6 分钟。

hot3.png

闭包即闭包是指可以包含自由(未绑定到特定对象)变量的代码块.表现出来是调用函数结束后,函数内的变量的生存周期拉长到调用者的生命。很多闭包实现成匿名函数(js也是表现成匿名函数的,其他的方法不清楚),3.0中引入了匿名函数,相应的也提供了闭包的支持。

闭包实例:

class Program    {        static void Main(string[] args)        {            Action ss = bibao();            ss();            Console.ReadKey();        }        public static Action bibao()        {            int i = 100;            return delegate {                Console.WriteLine(i);            };        }    }

通常情况下{}内的变量在结束后会结束生命周期,然而在这里ss()却可以打印出i的值。生命周期从bibao函数里面拉长到Main里面。

 

在js里面是通过函数对象之间作用域链的引用关系实现,那么在c#中又是用什么方法实现的呢?

反编译代码:

210630_PndQ_2403989.png

编译后的代码生成了一个新的类,c#的闭包就是建立在这个类的基础上面的。210832_EkAI_2403989.png

其中闭包中的变量作为类的公开成员变量,闭包函数自身作为成员,类型是internal。因为此类和闭包函数所在的类生成在一个同一个程序集中,而闭包流程中并不会使用这个类与其他程序集直接交流。

具体的调用过程

Main中:

.method private hidebysig static void  Main(string[] args) cil managed{  .entrypoint  // Code size       17 (0x11)  .maxstack  8  IL_0000:  call       class [mscorlib]System.Action ExtendMwthod.Program::bibao()  IL_0005:  callvirt   instance void [mscorlib]System.Action::Invoke()  IL_000a:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()  IL_000f:  pop  IL_0010:  ret} // end of method Program::Main

直接调用的依然是bibao方法,再invoke,没发现原因。

.method public hidebysig static class [mscorlib]System.Action         bibao() cil managed{  // Code size       25 (0x19)  .maxstack  8  IL_0000:  newobj     instance void ExtendMwthod.Program/'<>c__DisplayClass1_0'::.ctor()  IL_0005:  dup  IL_0006:  ldc.i4.s   100  IL_0008:  stfld      int32 ExtendMwthod.Program/'<>c__DisplayClass1_0'::i  IL_000d:  ldftn      instance void ExtendMwthod.Program/'<>c__DisplayClass1_0'::'
b__0'() IL_0013: newobj instance void [mscorlib]System.Action::.ctor(object, native int) IL_0018: ret} // end of method Program::bibao

可以看到自动生成的类在这里实例化了,闭包函数内部已经改写了。起始用字段i和方法'<bibao>b__0'实例化了action,因而在main中调用的时候变量已经包含在action的参数里面带过去了。通过这种方法实现了变量生命周期的延长。

 

 

转载于:https://my.oschina.net/hunjixin/blog/679175

你可能感兴趣的文章
oracle惯用缩写的含义
查看>>
boost.asio包装类st_asio_wrapper开发教程(2014.5.23更新)(一)-----转
查看>>
[CLR via C#]5.3 值类型的装箱和拆箱
查看>>
c语言中的位移位操作
查看>>
趋势型指标——MACD
查看>>
object-c语言的nonatomic,assign,copy,retain的区别
查看>>
Ubuntu12.04版本安装arm-linux-gcc 4.3.3
查看>>
js 正则之检测素数
查看>>
linux-多线程
查看>>
中国版 Ubuntu Kylin 14.04 LTS 麒麟操作系统中文版发布下载 (Ubuntu天朝定制版)
查看>>
hdu-----(4514)湫湫系列故事——设计风景线(树形DP+并查集)
查看>>
第40周二
查看>>
用户注册
查看>>
使用虚拟机运行Ubuntu时,主机与宿主机共享文件的方法。
查看>>
做一个略调皮的个人主页--相册与随笔篇
查看>>
EJB究竟是什么,真的那么神奇吗??
查看>>
Python 转义符
查看>>
海茶3 らぶデス3 入门经典教程
查看>>
pstree命令
查看>>
css选择器顺序的小技巧
查看>>