我觉得我对闭包有很好的理解,如何使用它们,以及它们什么时候有用.但我不明白的是他们实际上是如何在幕后的幕后工作的.一些示例代码:
public Action Counter()
{
int count = 0;
Action counter = () =>
{
count++;
};
return counter;
}
Run Code Online (Sandbox Code Playgroud)
通常,如果闭包没有捕获{count},它的生命周期将被限定为Counter()方法,并且在它完成之后它将消除Counter()的其余堆栈分配.什么时候关闭会发生什么?这个Counter()调用的整个堆栈分配是否存在?它会将{count}复制到堆中吗?它是否从未真正在堆栈上分配,但被编译器识别为关闭,因此总是存在于堆上?
对于这个特殊的问题,我主要关注它在C#中是如何工作的,但是不反对与支持闭包的其他语言进行比较.
我一直在脑子里反复思考,而且我似乎无法想出为什么C#闭包是可变的.如果您不知道究竟发生了什么,这似乎是一种获得意想不到的后果的好方法.
也许一个知识渊博的人可以阐明为什么C#的设计者会允许状态在闭包中改变?
例:
var foo = "hello";
Action bar = () => Console.WriteLine(foo);
bar();
foo = "goodbye";
bar();
Run Code Online (Sandbox Code Playgroud)
这将为第一个呼叫打印"hello",但外部状态在第二个呼叫时改变,打印"再见".更新了闭包的状态以反映局部变量的更改.