`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行代码完全不涉及它。
为什么选择这种设计?
- 与传统using块行为一致:
using var是C# 8.0引入的语法糖,本质是简化传统的using()块写法,保持行为一致性能降低开发者的学习成本,避免混淆。 - 避免意外错误:如果编译器允许在最后一次使用后就提前
Dispose,那么如果开发者后续误写代码再次引用该变量,就会触发已释放对象的异常。而块末尾Dispose的逻辑更符合开发者对“作用域”的常规认知——变量在整个块内都可用。
内容的提问来源于stack exchange,提问作者geekley
相关产品推荐
相关产品推荐

