我有如下代码:
private void SetupCheeseShop(Button buyCheese, Button spoilCheese)
{
var cheeseCount = 0; // No cheese
spoilCheese.Click += (sender, e) => {
// "Access to Modified Closure" warning occurs for cheeseCount below:
MessageBox.Show(string.Format("{0} cheeses have spoiled", cheeseCount));
cheeseCount = 0; // Throw out moldy cheese
};
buyCheese.Click += (sender, e) => {
cheeseCount++;
};
}
ReSharper警告我,当我从变质奶酪处理程序中的cheeseCount
读取时,我正在访问修改的闭包。在这种情况下,我可以安全地忽略它吗?
我希望在调用第一个闭包之间修改奶酪计数,但我不确定当代码在围绕同一变量的第二个闭包中进行修改时会发生什么。
您可以放心地忽略此警告。它警告您,关闭的over变量在创建闭包时可能具有与当前值(0)不同的值。这就是你想要的。你可以有任意数量的闭包,它们都引用同一个变量。可以把闭包变量看作类中的一个字段(这是编译器生成的)。
如c#语言规范4.0第5.1.7节所述:
如果局部变量被匿名函数捕获(§7.15.5.1),其生命周期至少延长到委托或从匿名函数创建的表达式树,以及任何引用捕获的变量的其他对象是符合垃圾收集条件。
你可以放心地依赖这种行为:变量保持不变,不管有多少匿名函数引用它,直到事件处理程序被收集,这是不会发生的,直到按钮本身在你的例子中被收集。
您的cheeseCount变量不是一个字段,并且您的变量的作用域仅在您自己的方法中。
你应该把cheeseCount移出你的方法,让它成为一个字段。