我有以下代码:
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
读取时,我正在访问修改后的闭包。在这种情况下,我可以放心地忽略它吗?
我期望在第一个闭包的调用之间修改干酪计数,但是我不确定当进行修改的代码是在同一个变量的第二个闭包中时会发生什么。
答案 0 :(得分:2)
您可以放心地忽略您的情况下的警告。它警告您,关闭的变量可能具有与创建闭包时的当前值(0)不同的值。这就是你想要的。你可以有任意数量的闭包,它们都引用相同的变量。将闭包变量视为类中的字段(编译器生成的字段)。
如C# Language Specification 4.0的第5.1.7节所述:
如果匿名函数捕获局部变量 (§7.15.5.1),其有效期至少延长至代表或 从匿名函数创建的表达式树,以及任何 其他引用捕获变量的对象是 有资格进行垃圾收集。
您可以放心地依赖此行为:无论有多少匿名函数引用它,变量都保持不变,直到收集事件处理程序,直到您的示例中收集按钮本身才会发生。< / p>
答案 1 :(得分:0)
您的cheeseCount变量不是字段,变量的范围仅在您自己的方法中。
你应该将cheeseCount从你的方法中移出并使它成为一个领域。