欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > c# lambda表达式关于 闭包 的知识点讲解

c# lambda表达式关于 闭包 的知识点讲解

2024/10/25 18:27:56 来源:https://blog.csdn.net/2401_82978699/article/details/143123734  浏览:    关键词:c# lambda表达式关于 闭包 的知识点讲解

话不多说 先上代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace _1.lambda表达式
{class Program{static void Main(string[] args){Text t = new Text();t.DoSomething();}}class Text{public event Action action;public Text(){int value = 10;//这里就形成了闭包//因为 当构造函数执行完毕时  其中申明的临时变量value的声明周期被改变了action = () =>{Console.WriteLine(value);Console.WriteLine("\n");};for(int i = 0;i < 10;i++){action += () =>{Console.WriteLine(i);};}}public void DoSomething(){action();}}
}

打印结果

 按我的理解,因为 i 一直都是同一个 我们添加函数到事件中最后 i 是 10 所以最后都会打印10 闭包遇到这种情况也可以解决  话不多说 上代码

for(int i = 0;i < 10;i++){//此team 非彼indexint team = i;action += () =>{Console.WriteLine(team);};}

打印结果

 

此时我们每一次进入循环都会定义一个变量 team 这样子大家都有自己的值 而不是 同一个 i 了

总结 

闭包确实会捕获它们被创建时的上下文变量,但是当你将这些闭包作为事件处理程序添加到一个事件时,你需要小心它们是如何被触发的。

在你的 Text 构造函数中,你做了两件事情:

  1. 你创建了一个闭包,它捕获了局部变量 value,并将其赋值给 action 事件。
  2. 你在一个循环中创建了10个额外的闭包,每个闭包都捕获了循环变量 i 的当前值,并将它们添加到 action 事件。

然而,这里有几个关键点需要注意:

  • 当你将闭包添加到事件时,你实际上是在将一个委托(delegate)添加到事件的调用列表中。
  • 每个委托都持有它自己被创建时的上下文,包括捕获的变量。
  • 但是,由于你在循环中添加了闭包,并且循环变量 i 是被闭包捕获的,所以所有的闭包实际上都捕获了同一个循环变量的引用。
  • 循环结束后,i 的值将是循环的最后一个值,即10。因此,当你触发 action 事件时,所有在循环中添加的闭包都会打印出 i 的最终值,即10。

这是为什么你看到所有的打印都是10的原因。

为了修复这个问题,并确保每个闭包都捕获循环中 i 的不同值,你可以引入一个局部变量来存储 i 的当前值,并在每个闭包内部使用这个局部变量。这样,每个闭包都会捕获它自己的局部变量,而不是共享同一个循环变量。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com