c#入门-捕获变量

文章讨论了C#中局部函数和匿名函数如何捕获局部变量,即使在变量作用域消失后仍能保持引用。编译器会创建一个内部类来保存这些变量。然而,引用类型如ref、in和out参数不能被捕获。示例展示了在for循环中使用闭包时可能出现的问题以及如何通过复制变量解决。对于foreach循环,由于其编译后的实现方式,捕获的变量不会引发相同问题。
摘要由CSDN通过智能技术生成

局部变量捕获

局部函数,匿名函数,可以直接在函数体内使用局部变量。
如果作为委托使用,传递给别人。可能在别人使用委托的时候,这些局部变量的作用域就已经消失了。

因此,编译器会对这些变量做出特殊的操作,将这些变量封装在一个类里面(编译器自己创建的类)。
在原变量出了作用域后,因为在封装类里面还有引用,不会被清除。
在这里插入图片描述
在这里插入图片描述

不可捕获的变量

引用变量(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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值