C#_闭包陷阱

如果匿名方法(Lambda表达式)引用了某个局部变量,编译器就会自动将该引用提升到该闭包对象中。

即将for循环中的变量i修改成了引用闭包对象的公共变量i。这样一来,即使代码执行后离开了原局部变量i的作用域(如for循环),包含该闭包对象的作用域也还存在。

推荐:局部变量不要同时放入匿名方法内,防止闭报陷阱。

//错误:55555,

//委托就是一个类,当对其进行实例化的时候,要将引用方法作为它构造函数的参数。

//通过反编译,可以看到执行匿名方法会生成一个类,然后去执行这个类的闭包对象里的方法。可以验证这一点。

delegate void test();
        static void Main(string[] args)
        {
            List<test> list= new List<test>();
            for (int i = 0; i < 5; i++)
            {
                test t = delegate { Console.WriteLine(i); };
                list.Add(t);
            }
            foreach (test t in list)
            {
                t();//即便离开for作用域,t执行里的i作用域还在(保留那个5)
            }
        }

//正确01234       

delegate void test();
        static void Main(string[] args)
        {
            List<test> list= new List<test>();
            for (int i = 0; i < 5; i++)
            {
                int temp=i;
                test t = delegate { Console.WriteLine(temp); };
                list.Add(t);
            }
            foreach (test t in list)
            {
                t();
            }
        }

 

posted @ 2016-05-30 10:36  shinchan  阅读(307)  评论(0)    收藏  举报