为什么在using语句中声明的变量被视为只读?

Sal*_*leh 5 .net c# using-statement object-lifetime

为什么using变量被视为只读?它是c#语言规范还是托管语言规范?这是因为c#是.net语言?提前致谢.

注意:using变量是在using语句中出现的变量

示例代码:

using (Form s = new Form)
{
    myfunc(ref s);
}
Run Code Online (Sandbox Code Playgroud)

我们无法在使用块中更改using变量的值.代码会引发错误.

注意:我不想让你讨论readonly关键字.

Ben*_*zun 11

我现在正在看一个(过时的?)规范[1].

15.13表示您在资源获取部分中声明的变量是只读的.那是:

var form = new Form1();
using (form) {
    form = null;
}
Run Code Online (Sandbox Code Playgroud)

有效,但是

using (var form = new Form1()) {
    form = null;
}
Run Code Online (Sandbox Code Playgroud)

没有.这回答了部分问题(即为什么?因为它是规范的一部分......),但我知道这并不令人满意.但你为什么要这样做呢?


编辑:在考虑了这个之后,让我为这个规则提供一个可能的解释:

你有

using (var something = new Foo()) {
   something = /* whatever */
}
Run Code Online (Sandbox Code Playgroud)

并且编译器允许这样做.现在如果Foo需要大量非托管资源(也许这就是你想要首先使用的原因using)怎么办?在使用块后,您无法再访问此引用.它没有被处理,因为你重新分配something并忘了自己处理它.您根本无法保证GC运行.或者何时.您刚刚创建了一个隐藏和隐藏的资源泄漏.


最后一个,灵感来自Henk与Eric Lippert博客的链接,该博客最终再次向我们抛出规范:

表格的使用声明

使用(表达式)语句

具有相同的两个可能的扩展,但在这种情况下,ResourceType隐式地是表达式的编译时类型,并且资源变量在嵌入语句中是不可访问的,并且是不可访问的.

换一种说法:

var form = new Form1();
using (form) {
    form = null;
}
Run Code Online (Sandbox Code Playgroud)

工作,因为这扩展到

var form = new Form1();
var invisibleThing = form;
try {
   form = null;
} finally {
    if (invisibleThing != null) ((IDisposable)invisibleThing).Dispose();
}
Run Code Online (Sandbox Code Playgroud)

因此,在这种情况下,您对using参考没有影响的事实只是对您隐藏,并且与前一种情况完全相同.

1:HTTP://www.ecma-international.org/publications/standards/Ecma-334.htm