20 闭包

  20.7 闭包的概念。内层函数引用的外层函数的变量的最终值。
我们预期的输出是, jiejiep, xiaoyi, zhangzetian
但是实际我们运行后发现,程序会报错,提示索引超出界限。
为什么没有达到我们预期的效果呢?让我们再来看一下闭包的概念。内层函数引用的外层函数的变量的最终值。就是说,当线程中执行方法时,方法中的i参数的值,始终是userList.Count。原来如此,那我们该如何
避免闭包陷阱呢?C#中普遍的做法是,将匿名函数引用的变量用一个临时变量保存下来,然后在匿名函数中使用临时变量。

	List<UserModel> userList = new List<UserModel>
	{
		new UserModel{ UserName="jiejiep", UserAge = 26},
		new UserModel{ UserName="xiaoyi", UserAge = 25},
		new UserModel{ UserName="zhangzetian", UserAge=24}
	};

	for (int i = 0; i < 3; i++)
	{
		UserModel u = userList[i];
		ThreadPool.QueueUserWorkItem((obj) =>
		{
			//TODO
			//Do some process...
			//...
			Thread.Sleep(1000);
			//UserModel u = userList[i];
			Console.WriteLine(u.UserName);
		});
	}

5.5 匿名方法中的捕获变量

        static MethodInvoker CreateInvoker()
        {
            int count = 5;
            MethodInvoker ret = delegate
              {
                  Console.WriteLine(count);
                  count++;
              };
            ret();
            return ret;
        }

5.5.4 捕获变量的延长生存期

        static void Main(string[] args)
        {
            MethodInvoker m = CreateInvoker();
            m();
            m();

            Console.ReadKey();
        }
        static MethodInvoker CreateInvoker()
        {
            int count = 5;
            MethodInvoker ret = delegate
              {
                  Console.WriteLine(count);
                  count++;
              };
            ret();
            return ret;
        }

由循环的初始部分声明的变量只被实例化一次。这很容易弄错!如果你想捕获循环变量在一次特定的循环迭代中的值,必须在循环内部引入另一个变量,并将循环变量的值复制给它,再捕捉那个新变量

        static void Main(string[] args)
        {
            MethodInvoker m = CreateInvoker();
            m();
            m();

            Console.ReadKey();
        }
        static MethodInvoker CreateInvoker()
        {
            int count = 5;
            MethodInvoker ret = delegate
              {
                  Console.WriteLine(count);
                  count++;
              };
            ret();
            return ret;
        }

  

原文地址:https://www.cnblogs.com/kikyoqiang/p/10152532.html