为什么using
变量被视为只读?它是c#语言规范还是托管语言规范?这是因为c#是.net语言?提前谢谢。
注意:using变量是使用语句
中出现的变量示例代码:
using (Form s = new Form)
{
myfunc(ref s);
}
我们无法在使用块中更改using变量的值。代码会引发错误。
注意:我不希望您讨论readonly关键字。
答案 0 :(得分:11)
我正在看一个(过时的?)规范[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需要大量非托管资源(也许这就是你想要首先使用using
的原因)?在使用块后,您无法再访问此引用。它没有被处理,因为你重新分配了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
答案 1 :(得分:4)
如果你的意思是在使用块开始时实例化的变量,那么它只是读取,因为它需要被放置在块的末尾。使用块的目的是以可预测的方式销毁资源,而不是等待垃圾收集器完成它的工作。
答案 2 :(得分:2)
首先,在您的示例中,ref
修饰符很可能没有理由。
所以你问一个非常理论化的问题,它在实践中从来都不是问题。
带注释的C#3手册没有给出解释。
Eric Lippert在帖子about (not) Boxing in a using statement中触及了这个主题。
我自己捅了一下:
编译器使受控var只读,因为它可以。让这个var可写可以打开更多的蠕虫,请参阅Eric的Boxing文章。请注意,类似的规则适用于foreach()
中的封闭变量。基本上,写入这些变量永远不会有用,因此编译器可以最大限度地控制它们。
答案 3 :(得分:1)
readonly是C#中的关键字。当您想要确保值永远不会在构造函数外部更改时,它非常有用。
当您为大型项目贡献代码时,此关键字可能会有所帮助,而您担心同事可能会尝试更改永远不应更改的变量。
编辑:我很好奇为什么有人对我的回答进行了低估。如果投票给谁,请告诉我我的答案错在哪里?感谢。