C#-如何在lambda中修改局部变量?

时间:2019-06-13 00:01:15

标签: c# lambda garbage-collection

  

在Java中,像这样修改局部变量将导致:

     

Local variable i defined in an enclosing scope must be final or effectively final

但是,翻译成c#的相同代码可以正常工作

int i = 0;

Timer timer = new Timer(1);
timer.Elapsed += (source, arg) => {
    i++;
};
timer.AutoReset = false;
timer.Enabled = true;

Console.WriteLine(i);
System.Threading.Thread.Sleep(100);
Console.WriteLine(i);
  

0

     

1

这怎么可能?垃圾收集器如何知道何时处置诸如i之类的变量?

2 个答案:

答案 0 :(得分:3)

在c#中,闭包关闭变量而不是值。 lambda保留对i的引用,而不是值。对i的外部更改对于lambda是可见的,反之亦然。

此答案可能会帮助https://stackoverflow.com/a/22412790/235354

答案 1 :(得分:3)

它通过 closure

完成

closure 是一段代码,可以在以后执行,但是保留并维护了使用编译器生成的类首次创建该代码的环境。即使该方法完成后,它仍然可以使用局部变量,垃圾收集器会维护对所需内容的引用计数,而不会收集到任何本不应该收集的内容