You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

`using var`何时被销毁?作用域是块末尾还是最后使用后?

using 局部变量的生存期将延长至其声明所在作用域的末尾。随后,using 局部变量将按声明的相反顺序被销毁。

关于using局部变量作用域的疑问

我的问题是:using 局部变量何时被视为超出作用域?

  • 一定是在代码块的末尾吗?
  • 一定是在块中最后一次使用它之后吗?
  • 还是由实现定义,因此可能是其中任意一种情况,甚至介于两者之间?

换句话说:

{
  using var res = Res();
  res.DoStuff();
  somethingElse.DoWhatever();
  res.DoMoreStuff();
  // 100 more statements that have nothing to do with res
}

这是否始终等同于以下代码(1)?

{
  using (var res = Res()) {
    res.DoStuff();
    somethingElse.DoWhatever();
    res.DoMoreStuff();
    // 100 more statements that have nothing to do with res
  }
}

还是始终等同于以下代码(2)?

{
  using (var res = Res()) {
    res.DoStuff();
    somethingElse.DoWhatever();
    res.DoMoreStuff();
  }
  // 100 more statements that have nothing to do with res
}

或者这只是实现细节?
规范对此有定义吗?这种“作用域”在技术上指的是什么?如果上述某一种情况始终成立,那么偏好该行为的原因是什么?我原本认为(2)更好,但可能我错了。

我知道这对高级编程来说可能影响不大,但我对此很好奇。


解答

首先明确:using局部变量的行为完全等同于代码(1),而非代码(2),这是C#语言规范明确规定的,并非实现细节。

核心规则

C#规范中定义:using声明(using var)的变量,其作用域是声明它的代码块(即包裹它的{}范围),变量的销毁与Dispose调用会在该代码块的末尾执行,并且多个using变量会按声明的逆序处理。

也就是说,你示例中的res会在整个大括号内保持有效,直到块内所有代码执行完毕后才会被Dispose,哪怕后面的100行代码完全不涉及它。

为什么选择这种设计?

  1. 与传统using块行为一致:using var是C# 8.0引入的语法糖,本质是简化传统的using()块写法,保持行为一致性能降低开发者的学习成本,避免混淆。
  2. 避免意外错误:如果编译器允许在最后一次使用后就提前Dispose,那么如果开发者后续误写代码再次引用该变量,就会触发已释放对象的异常。而块末尾Dispose的逻辑更符合开发者对“作用域”的常规认知——变量在整个块内都可用。

内容的提问来源于stack exchange,提问作者geekley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 20:50:29