博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅谈.NET中闭包
阅读量:5084 次
发布时间:2019-06-13

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

什么是闭包

    闭包可以从而三个维度来说明。在编程语言领域,闭包是指由函数以及与函数相关的上下文环境组合而成的实体。通过闭包,函数与其上下文变量之间建立起关联关系,上下文变量的状态可以在函数的多次调用过程中持久保持。从作用域而言,私有变量的生命周期被延长,函数调用所生成的值在下次调用时仍被保持。从安全性而言,闭包有利于信息的隐蔽,私有变量只在该函数内可见。

.NET中的闭包

    说起闭包,可对会想起JavaScript。在JavaScript语言中,闭包可以说是无处不在。同样,.NET中也有闭包。只不过实现方式和JavaScript不太一样。

通常而言,形成闭包有一些值得总结的非必要条件:

  • 嵌套定义函数
  • 匿名函数
  • 将函数作为参数或返回值

    在.NET中,函数并不是第一级成员,所以并不能像JavaScript那样通过嵌套子函数的方式实现闭包。但.NET可以通过匿名委托形成闭包。

delegate void HelloDelegate();        static void Main(string[] args)        {            string str = "Hello World!";            HelloDelegate hello = delegate()            {                Print(str);            };        }        private static void Print(string str)        {            Console.WriteLine(str);        }

反编译上面的IL代码:

如上图所示,编译器自动生成了一个内部类,变量strb变成这个类的字段,即使创建该变量的方法(Main)执行结束,该变量也不会释放,而是在所有回调函数执行之后才被GC回收。这就是.NET实现闭包的原理。

闭包带来的问题

如下面代码:

static void Main()        {            IList
actions = new List
(); for (int i = 0; i < 5; i++) { actions.Add(() => Console.WriteLine(i)); } foreach (var action in actions) { action(); } }

先猜猜输入的值是什么,如果猜的0、1、2、3、4的话就错了。应该全是4。那为什么呢?因为闭包具有延迟的和数据共享的特性,只有当调用action()方法时才会获取i的值,这是i的值经过i++已经变成4,又因为所有的action都会获取同一个i值,所以最后输出的值都为4。

那怎么解决呢?通常解决方法时在循环中加入中间量。

for (int i = 0; i < 5; i++)            {                int j = i;                actions.Add(() => Console.WriteLine(j));            }

转载于:https://www.cnblogs.com/Khadron/p/Closure.html

你可能感兴趣的文章
JSON 简单例子
查看>>
UCOS 中的中断处理
查看>>
异步编程设计模式Demo - PrimeNumberCalculator
查看>>
第三次作业-结对编程
查看>>
Python全栈开发——线程与进程(进程)
查看>>
mysql数据导出乱码
查看>>
Ryzom相关的项目简介
查看>>
新版.Net开发必备十大工具(转)
查看>>
noi.ac NA531 【神树和物品】
查看>>
冒泡排序
查看>>
ZZUOJ 10509 组合数学+乘法逆元
查看>>
python【项目】:选课系统【简易版】
查看>>
UESTC--1682
查看>>
error C4430: 缺少类型说明符 - 假定为 int
查看>>
前后端数据交互之格式
查看>>
Hello
查看>>
axios的get,post方法
查看>>
awk条件语句
查看>>
linux下如何启动sybase
查看>>
使用HTML实现对汉字拼音的支持
查看>>