• 浅谈.NET中闭包


    什么是闭包

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

    .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代码:

    S)TV14[6U~P`@NY6G~$}2UK

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

    闭包带来的问题

    如下面代码:

     static void Main()
            {
                IList<Action> actions = new List<Action>();
    
                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));
                }

    N}$8(%MX}MUPZ}YVDY3GGJB

  • 相关阅读:
    每日一题20201109(15. 三数之和)
    每日一题20201106(169. 多数元素)
    每日一题之20201103(941. 有效的山脉数组)
    每日一题之20201102(349. 两个数组的交集)
    【USACO4.4】追查坏牛奶
    【九省联考2018】一双木棋
    【NOI2013】向量内积
    【HNOI2013】游走
    【ZJOI2008】骑士
    【HEOI2014】大工程
  • 原文地址:https://www.cnblogs.com/Khadron/p/Closure.html
Copyright © 2020-2023  润新知