在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
之类的变量?
答案 0 :(得分:3)
在c#中,闭包关闭变量而不是值。 lambda保留对i
的引用,而不是值。对i
的外部更改对于lambda是可见的,反之亦然。
答案 1 :(得分:3)
它通过 closure
完成closure 是一段代码,可以在以后执行,但是保留并维护了使用编译器生成的类首次创建该代码的环境。即使该方法完成后,它仍然可以使用局部变量,垃圾收集器会维护对所需内容的引用计数,而不会收集到任何本不应该收集的内容