局部函数,匿名函数,可以直接在函数体内使用局部变量。
如果作为委托使用,传递给别人。可能在别人使用委托的时候,这些局部变量的作用域就已经消失了。
因此,编译器会对这些变量做出特殊的操作,将这些变量封装在一个类里面(编译器自己创建的类)。
在原变量出了作用域后,因为在封装类里面还有引用,不会被清除。
引用变量(ref变量,in参数,out参数),和ref结构不允许被捕获。
委托捕获的变量是以引用传递的方式使用的。
也就是说,如果使用和捕获之间修改了捕获的变量,那么使用时是修改后的结果。
Action act =null;
for (int i = 0; i< 10; i++)
{act += () =>Console.WriteLine(i);
}
act();//输出结果全是10
如果希望使用声明委托当时的值,只需要另外声明一个局部变量进行复制操作。
引用类型的复制可能需要使用深拷贝。
Action act =null;
for (int i = 0; i< 10; i++)
{int j=i;
act += () =>Console.WriteLine(j);
}
act();//输出0到9
附注foreach循环和for循环不同。
foreach循环是一个语法糖,在编译后不会呈现出foreach循环,而是while循环。
然后,在foreach循环中生命的变量,在编译后,是在while循环内声明的。
也就是说foreach循环中捕获item,不会出现上述for循环的问题。
int[] i = {1, 2, 3, 4, 5 };
Action action = null;
foreach (var item in i)
{action += () =>Console.WriteLine(item);
}
action();//确实是1,2,3,4,5
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧