JetBrains Rider 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); };

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

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

其中一种可能发生的情况是闭包定义在 示意图 语句内部:

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

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

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

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

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

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