ReSharper 2025.2 Help

代码检查:访问已释放的捕获变量

首先,让我们确保您理解什么是 闭包。 简单来说,C# 中的闭包是一个捕获了外部作用域中某些变量的 lambda 表达式或匿名方法。 以下是最简单的示例:

// A self-contained lambda. Not a closure. Action printOne = () => { Console.WriteLine("one"); }; // A closure – a lambda that captures a variable from an outer scope. string myStr = "one"; Action print = () => { Console.WriteLine(myStr); };

在上面的示例中, print 将捕获变量 myStr (而不是其 ),并且仅在您调用 print() 时获取 myStr

在更复杂的场景中,当闭包定义在一个变化的上下文中时,它可能不会按预期运行。

可能发生这种情况的情形之一是闭包定义在 using 语句内部:

void Foo(string fileName, string text) { using (var writer = new StreamWriter(fileName)) { ExecuteDelayed(() => { writer.Write(text); }); } } private static void ExecuteDelayed(Action action) { // execute action }

在上述代码中,ReSharper 会针对 writer.Write(text); 发出 访问已释放的闭包警告。 原因是 ExecuteDelayed() 可能会在 writer 的作用域被释放后执行 lambda,这将导致运行时异常。

如果 ExecuteDelayed() 在堆栈上完成了对 lambda 的处理,您可以使用 InstantHandle属性标记 action 参数:

private static void ExecuteDelayed([InstantHandle]Action action) { // execute action }

这将告诉 ReSharper 的代码分析引擎,在这种上下文中使用 ExecuteDelayed() 是安全的,不会发出任何警告。

最后修改日期: 2025年 9月 27日