• C#:在匿名方法中捕获外部变量


    先来一段代码引入主题。如果你可以直接说出代码的输出结果,说明本文不适合你。(代码引自《深入理解C#》第三版)

        class Program
        {
            private delegate void TestDelegate();
     
            static void Main(string[] args)
            {
                TestDelegate[] delegates = new TestDelegate[2];
    
                int outside = 0;
    
                for(int i = 0; i < 2; i++)
                {
                    int inside = 0;
    
                    delegates[i] = delegate
                    {
                        Console.WriteLine("({0},{1})", outside, inside);
                        outside++;
                        inside++;
                    };
                }
    
                delegates[0]();
                delegates[0]();
                delegates[0]();
    
                delegates[1]();
                delegates[1]();
    
                Console.ReadKey();
            }
        }

    答案在本文最下方。

    先引入两个定义:

    1、外部变量:是指作用域内包括匿名方法的局部变量或参数。

    2、捕获的外部变量:是指在匿名方法中使用的外部变量。

    定义有点抽象,针对上面的代码而言,inside和outside都是匿名方法的外部变量,而inside和outside同样也作为被匿名方法捕获的外部变量,因为在匿名方法体中引用了这两个变量。

    而被匿名方法捕获到的是变量本身,而并非变量的值。针对上面的代码而言,执行outside++和inside++时,操作的其实就是外部的inside和outside变量。

    至此,我们应该可以得出outside的变化应该是从0到4。

    那么程序的输出也应该是这个样子的:(X代码未知)

    (0,X)

    (1,X)

    (2,X)

    (3,X)

    (4,X)

    实际上,在for循环体里面做的东西就是实例化了两个TestDelegate委托对象:delegate[0]和delegate[1]

    而循环的执行,实际上会实例化两个名称都为inside的变量。

    这两个变量之间没有什么关联,仅仅是名称一样而已。

    这两个变量分别作为delegate[0]和delegate[1]的外部捕获变量。也就是delegate[0]和delegate[1]在操作inside时,是互不影响的。

    于是,得出答案:

    0,0)
    
    (1,1)
    
    (2,2)
    
    (3,0)
    
    (4,1
    答案
  • 相关阅读:
    互联网架构的三马车
    云时代架构读后感
    支付宝架构师眼里的高并发架构
    支付宝架构
    架构层级的“开闭原则”2
    架构层级的“开闭原则”1
    互联网架构微服务
    关于第三方支付
    分布式架构中数据一致性常见的几个问题
    Java多线程学习笔记二
  • 原文地址:https://www.cnblogs.com/DoNetCoder/p/4355738.html
Copyright © 2020-2023  润新知