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

标签 c# .net using-statement object-lifetime

为什么 using block 中的变量 (myform) 被视为只读,当我尝试将其作为函数引用传递时编译器会引发错误。

示例代码:

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

将 using 变量作为 ref 传递给函数会引发错误。因此上面的代码会引发错误。

注意:“只读”关键字与我的问题无关。

最佳答案

我正在查看(过时的?)规范 [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 的原因)?在 using block 之后,您将无法再访问此引用。它没有被处置,因为你重新分配了 something 而忘了自己处理它。您根本无法保证 GC 会运行。或者什么时候。您刚刚制造了一个被掩盖和隐藏的资源泄漏。


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

A using statement of the form

using (expression) statement

has the same two possible expansions, but in this case ResourceType is implicitly the compile-time type of the expression, and the resource variable is inaccessible in, and invisible to, the embedded statement.

换句话说:

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

关于c# - 为什么在 using 语句中声明的变量被视为只读?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6001280/

相关文章:

c# - 使用泛型类型和表达式的扩展方法选择

postgresql - 使用 EXECUTE format( ... ) USING (param1, param2) 时没有参数 $2

c# - WithDegreeOfParallelism(N>CPU 数量)

c# - 实现两个接口(interface)的参数约束

c# - 在 .NET 中将小时数转换为分钟数

c#条件为真时在字符上拆分字符串

.net - 银光 4 PLINQ

c# - 同一 using block 中的多个变量

c# - Apache Active MQ .Net 客户端 (Apache NMS) 和 Visual Studio 2010 C# Express