C#实现在匿名方法中捕获外部变量的方法
程序员文章站
2023-12-12 14:43:04
先来一段代码引入主题。如果你可以直接说出代码的输出结果,说明本文不适合你。(代码引自《深入理解c#》第三版)
class program
{
pr...
先来一段代码引入主题。如果你可以直接说出代码的输出结果,说明本文不适合你。(代码引自《深入理解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)
答案