奇数λ行为 [英] odd lambda behavior

查看:109
本文介绍了奇数λ行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我偶然发现了这篇文章,发现它很有趣,所以我自己运行一些测试:



<$ p $

测试一: List< Action> actions = new List< Action>();

for(int i = 0; i <5; ++ i)
actions.Add(()=> Console.WriteLine(i));

foreach(动作中的动作)
action();

输出:

  5 
5
5
5
5






测试二:

 列表<动作> actions = new List< Action>(); 

for(int i = 0; i <5; ++ i)
{
int j = i;
actions.Add(()=> Console.WriteLine(j));
}

foreach(操作中的操作操作)
action();

输出:

  0 
1
2
3
4






根据文章,在Test One中,所有的lambdas都包含对 i 的引用,所有输出5.这是否意味着我在测试二中获得预期的结果,因为为每个lambda表达式创建了一个新的 int

解决方案

这是因为 变量捕获 在C#中可能有点棘手



简而言之,for循环的每个循环都引用相同的变量 i ,因此编译器对所有循环使用相同的lambda表达式。



如果是任何安慰,这个奇怪在JavaScript中更糟,因为javascript只有变量的函数范围,所以即使你的第二个解决方案不会做你期望的。 / p>

这也是一个很好的解释


I stumbled across this article and found it very interesting, so I ran some tests on my own:

Test One:

List<Action> actions = new List<Action>();

for (int i = 0; i < 5; ++i)
    actions.Add(() => Console.WriteLine(i));

foreach (Action action in actions)
    action();

Outputs:

5
5
5
5
5


Test Two:

List<Action> actions = new List<Action>();

for (int i = 0; i < 5; ++i)
{
    int j = i;
    actions.Add(() => Console.WriteLine(j));
}

foreach (Action action in actions)
    action();

Outputs:

0
1
2
3
4


According to the article, in Test One all of the lambdas contain a reference to i which causes them to all output 5. Does that mean I get the expected results in Test Two because a new int is created for each lambda expression?

解决方案

This is because of variable capturing in C# that can be a little tricky

In a nutshell, Each loop of the for loop is referring to the same variable i so the compiler uses the same lambda expression for all loops.

If it is any consolation, This oddity is worse in javascript as javascript only has function scopes for variables so even your second solution won't do what you expect it to.

This is also a very good explanation

这篇关于奇数λ行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆