当前位置: 首页 > 编程语言 > C#

C#中的lambda如何绑定foreach中的枚举数?分享

时间:2023-04-11 00:57:08 C#

C#中的lambda如何绑定foreach中的枚举数?我刚刚遇到了最意想不到的行为。我确信这是有充分理由的。有人可以帮忙解释一下吗?考虑以下代码:varnums=newint[]{1,2,3,4};varactions=newList();foreach(varnuminnums){actions.Add(()=>num);}foreach(varnuminnums){varx=num;动作.Add(()=>x);}foreach(varactioninactions){Debug.Write(action()+"");}outputpair让我有点吃惊:44441234显然,lambda如何引用枚举器。在foreach的第一个版本中,'num'实际上是绑定到'Current',而不是它返回的结果?这是关于lambda的众所周知和既定的行为,尽管对于那些第一次遇到它的人来说常常是令人惊讶的。根本问题是您对lambda的心理模型不太正确。lambda是一个在被调用之前不会运行的函数。您的闭包绑定了对该lambda实例的引用,而不是值。当你最后在foreach循环中做事时,这是你第一次真正查看关闭引用以了解它是什么。在第一种情况下,您引用的是num,此时num的值为4,因此当然所有输出都是4。在第二种情况下,每个lambda在每次循环中都在本地绑定到不同的值,并且值不会改变(它不会仅仅因为lambda引用而被GC处理。)所以你得到了你期望的答案。对本地临时对象的闭包实际上是从lambda中的某个时间点捕获特定值的标准方法。Adam到EricLippert博客的链接提供了更深入(并且技术上准确)的描述。请参阅EricLippert关于此问题的博客文章;它与迭代器变量在代码中的作用域有关,以及它如何应用于lambda闭包和提升函数。因为foreach结构只是语法糖,所以最好以它的真实形式来考虑它。整数;while(nums.MoveNext()){num=nums.Current;actions.Add(()=>num);}lambda将捕获num变量,因此当您执行lambda时,将使用num的最新值。这是因为两件事:1)委托持有外部变量的上下文(作用域)2)第一个foreach循环将只编译一个声明的“num”变量。3)惰性评估在第一个循环中添加的每个委托都将保存保存到范围中的相同num变量。因为延迟计算,你会在第一个循环完成后运行委托,所以保存到委托的范围等于4。参见关于lambda、捕获和可变性以上是C#学习教程:Howdoesthelambda在C#中绑定到foreach中的枚举数?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: