一尘不染

闭包如何在后台工作?(C#)

c#

我觉得我对闭包,如何使用它们以及什么时候有用非常了解。但是我不了解的是它们在内存中的幕后实际上是如何工作的。一些示例代码:

public Action Counter()
{
    int count = 0;
    Action counter = () =>
    {
        count++;
    };

    return counter;
}

通常,如果{count}没有被闭包捕获,则其生命周期将限制在Counter()方法范围内,并且在完成后它将与Counter()的其余堆栈分配一起消失。封闭时会发生什么?此Counter()调用的整个堆栈分配是否仍然存在?是否将{count}复制到堆?它是否从未真正分配到堆栈上,而是被编译器识别为已关闭,因此始终存在于堆中?

对于这个特定的问题,我主要对它在C#中的工作方式感兴趣,但不会反对与支持闭包的其他语言进行比较。


阅读 294

收藏
2020-05-19

共1个答案

一尘不染

所述 编译器
(而不是在运行时)创建另一个类/类型。带有您的闭包的函数以及您被闭包/吊起/捕获的所有变量都将作为该类的成员重新编写为整个代码。.Net中的关闭实现为该隐藏类的一个实例。

这意味着您的count变量完全是另一个类的成员,并且该类的生存期与任何其他clr对象一样;在不再生根之前,它不符合垃圾收集的条件。这意味着,只要您有对该方法的可调用引用,它就不会出现任何问题。

2020-05-19