我觉得我对闭包,如何使用它们以及什么时候有用非常了解。但是我不了解的是它们在内存中的幕后实际上是如何工作的。一些示例代码:
public Action Counter() { int count = 0; Action counter = () => { count++; }; return counter; }
通常,如果{count}没有被闭包捕获,则其生命周期将限制在Counter()方法范围内,并且在完成后它将与Counter()的其余堆栈分配一起消失。封闭时会发生什么?此Counter()调用的整个堆栈分配是否仍然存在?是否将{count}复制到堆?它是否从未真正分配到堆栈上,而是被编译器识别为已关闭,因此始终存在于堆中?
对于这个特定的问题,我主要对它在C#中的工作方式感兴趣,但不会反对与支持闭包的其他语言进行比较。
所述 编译器 (而不是在运行时)创建另一个类/类型。带有您的闭包的函数以及您被闭包/吊起/捕获的所有变量都将作为该类的成员重新编写为整个代码。.Net中的关闭实现为该隐藏类的一个实例。
这意味着您的count变量完全是另一个类的成员,并且该类的生存期与任何其他clr对象一样;在不再生根之前,它不符合垃圾收集的条件。这意味着,只要您有对该方法的可调用引用,它就不会出现任何问题。