简体   繁体   English

如何在C#中为变量创建闭包?

[英]How to create a closure for a variable in C#?

The following example prints the number "5" five times after 1 second. 下面的示例在1秒后五次打印数字“ 5”。

for (int i = 0; i < 5; ++i)
{
    EasyTimer.SetTimeout(() => Console.WriteLine(i), 1000);
}

(Assume EasyTime.SetTimeout behaves like JavaScript's setTimeout ) (假设EasyTime.SetTimeout行为类似于JavaScript的setTimeout

How can we create a closure around i such that it keeps it remembers its value for the callback? 我们如何围绕i创建闭包,以使其记住回调的值?

I know how to do it in JavaScript but I'm not sure if we can do it the same way in C#. 我知道如何在JavaScript中执行此操作,但不确定是否可以在C#中以相同的方式执行。

Inside the block, assign i to a new variable j, and use j in the lambda, as follows: 在块内,将i分配给新变量j,然后在lambda中使用j,如下所示:

for (int i = 0; i < 5; ++i)
{
    int j = i;
    EasyTimer.SetTimeout(() => Console.WriteLine(j), 1000);
}

Notably, this issue only crops up because the lambda is a closure over i , so it gets the value when the lambda executes, not when it's created. 值得注意的是,此问题只会出现,因为lambda i的闭包,因此它在lambda执行时(而不是在创建时)获得值。

If you are using C#5.0 you can write the following: 如果使用的是C#5.0,则可以编写以下内容:

foreach (int i in Enumerable.Range(0, 5))
{
    EasyTimer.SetTimeout(() => Console.WriteLine(i), 1000);
}

It will automatically generate local variable. 它将自动生成局部变量。 This will only work in foreach loop, not for. 这仅适用于foreach循环,不适用于for。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM