C#闭包简单解释

这段的输出结果是0/1/2.  也就是说i的值不断增加,但是我们知道, GetDelegate这个方法下的i这个值, 它是一个临时变量, 方法执行结束就应该销毁了,怎么会增加到2?

原理就是编译器检测到, 委托使用的变量i, 使用过程超出了其作用域, 就自动产生了一个闭包,具体而言就是生成了一个新的类.

把以上代码输进SharpLab, 看看编译器拿到的版本,

SharpLab

为了方便阅读,我已经用GPT转化成正常C#语言(等效代码):(调用的类没有变,不用看)

可看到, 编译器生成了一个内部类, 把临时变量转换为成员变量, 这这就是编译器生成的"闭包". 可以猜测Func委托内部维持了对counterClosure这个变量的引用, 所以只要委托存在,这个变量就不会被回收.

至于闭包陷阱, 是因为闭包原理而产生的反常识现象, 下次再说~

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C#中的闭包是指一个函数能够访问它外部的变量,即使这些变量在函数外部定义。闭包可以在函数内部创建,也可以作为函数的返回值返回。 下面是一个简单闭包示例: ``` public Func<int, int> Add(int a) { return b => a + b; } // 调用 Func<int, int> add5 = Add(5); int result = add5(3); // result = 8 ``` 在上面的代码中,Add方法返回一个匿名函数,这个匿名函数能够访问Add方法中的变量a。当我们调用Add(5)时,会返回一个函数,这个函数会将传入的参数b加上a,然后返回结果。 关于foreach中的闭包,需要注意的是,foreach循环变量会在每次迭代中重新赋值,因此如果在循环体内部使用匿名函数访问循环变量,可能会导致意外的结果。例如: ``` List<Func<int>> funcs = new List<Func<int>>(); int[] nums = { 1, 2, 3 }; foreach (int num in nums) { funcs.Add(() => num); } foreach (Func<int> func in funcs) { Console.WriteLine(func()); } ``` 上面的代码中,我们在第一个foreach循环中向一个List中添加了三个匿名函数,这些匿名函数都返回循环变量num。在第二个foreach循环中,我们依次调用了这三个函数,期望的结果是输出1、2、3。但实际上,输出的结果都是3,这是因为在第一个foreach循环中,循环变量num在每次迭代中都被重新赋值,而匿名函数中访问的是循环变量的引用,最终所有的函数都返回了最后一次迭代中的值3。 为了避免这种问题,我们可以在循环体内部创建一个局部变量来保存循环变量的值,然后在匿名函数中访问这个局部变量,例如: ``` List<Func<int>> funcs = new List<Func<int>>(); int[] nums = { 1, 2, 3 }; foreach (int num in nums) { int temp = num; funcs.Add(() => temp); } foreach (Func<int> func in funcs) { Console.WriteLine(func()); } ``` 这样就可以输出期望的结果了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值