gpt4 book ai didi

c# - C# 中的 lambda 如何绑定(bind)到 foreach 中的枚举数?

转载 作者:可可西里 更新时间:2023-11-01 08:08:58 25 4
gpt4 key购买 nike

我刚刚遇到了最意想不到的行为。我确信它以这种方式工作是有充分理由的。谁能帮忙解释一下?

考虑这段代码:

var nums = new int[] { 1, 2, 3, 4 };
var actions = new List<Func<int>>();

foreach (var num in nums)
{
actions.Add(() => num);
}

foreach (var num in nums)
{
var x = num;
actions.Add(() => x);
}

foreach (var action in actions)
{
Debug.Write(action() + " ");
}

输出结果让我有点意外:

4 4 4 4 1 2 3 4 

显然,lambda 引用枚举器的方式有问题。在foreach的第一个版本中,'num'实际上是绑定(bind)到'Current',而不是它返回的结果吗?

最佳答案

这是关于 lambda 的众所周知和既定的行为,尽管对于那些第一次遇到它的人来说经常会感到惊讶。根本问题是您对 lambda 是什么的心智模型不太正确。

lambda 是一个在被调用之前不会运行的函数。您的闭包绑定(bind)了对该 lambda 实例的引用,而不是值。当您在最终的 foreach 循环中执行您的操作时,这是您第一次真正跟随封闭引用以查看它是什么。

在第一种情况下,您引用的是 num,此时 num 的值为 4,因此您的所有输出当然都是 4。在第二种情况下,每个 lambda 都绑定(bind)到一个不同的值每次都是循环的本地值,并且该值没有改变(它没有仅仅因为 lambda 引用而被 GC。)因此,您得到了您期望的答案。

对局部临时值的闭包实际上是从 lambda 中的某个时间点捕获特定值的标准方法。

亚当的 link to Eric Lippert's blog对正在发生的事情提供了更深入(技术上更准确)的描述。

关于c# - C# 中的 lambda 如何绑定(bind)到 foreach 中的枚举数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2413706/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com