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

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

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

示例代码:

 using (Form s = new Form) { myfunc(ref s); } 

我们不能在使用块中更改using变量的值。 代码会引发错误。

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

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

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

 var form = new Form1(); using (form) { form = null; } 

工作,但

 using (var form = new Form1()) { form = null; } 

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


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

你有

 using (var something = new Foo()) { something = /* whatever */ } 

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


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

表格的使用声明

使用(表达式)语句

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

换一种说法:

 var form = new Form1(); using (form) { form = null; } 

有效,因为这扩大到了

 var form = new Form1(); var invisibleThing = form; try { form = null; } finally { if (invisibleThing != null) ((IDisposable)invisibleThing).Dispose(); } 

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

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

如果你的意思是在使用块的开头实例化变量,那么它只是读取,因为它需要被放置在块的末尾。 使用块的要点是以可预测的方式销毁资源,而不是等待垃圾收集器完成它的工作。

首先,在您的示例中,很可能没有理由使用ref修饰符。

所以你问一个非常理论化的问题,它在实践中从来都不是问题。

带注释的C#3手册没有给出解释。

Eric Lippert在一篇关于(不是)Boxing in a using声明的post中谈到了这个主题。

我自己捅了一下:

编译器使受控var只读, 因为它可以 。 让这个var可写可以打开更多的蠕虫,请参阅Eric的Boxing文章。 请注意,类似的规则适用于foreach()的封闭变量。 基本上,写入这些变量永远不会有用,因此编译器会对它们进行最大程度的控制。

readonly是C#中的关键字。 当您想要确保值永远不会在构造函数外部更改时,它非常有用。

当您为大型项目贡献代码时,此关键字可能会有所帮助,并且您担心同事可能会尝试更改永远不应更改的变量。

编辑 :我很好奇为什么有人低估了我的答案。 如果投票给谁,你可以告诉我我的答案是错的吗? 谢谢。