为什么c#不允许将using变量作为ref或out传递给函数

时间:2011-05-14 09:45:27

标签: c# pass-by-reference using-statement

  

可能重复:
  Passing an IDisposable object by reference causes an error?

为什么C#不允许将变量从使用块传递给函数作为ref或out?

这是我的代码:

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

函数在using块结束之前结束,为什么C#不允许我将s作为ref或out参数传递?

3 个答案:

答案 0 :(得分:23)

using变量被视为只读,因为任何重新分配都可能是错误。由于ref允许重新分配,这也是一个问题。在IL级别,outref完全相同。

但是,我怀疑你 需要 ref;您已经将引用传递给表单,因为它是一个类。对于参考类型,ref的主要目的是允许您 重新分配 变量,并让调用者看到重新分配,即

void doSomething(ref Form form)
{
    form = null; // the caller will see this change
}

如果您只是与表单对象交谈,则 是必需的:

void doSomething(Form form)
{
    form.Text = "abc"; // the caller will see this change even without ref
}

因为 是相同的表单对象

答案 1 :(得分:9)

using()语句中的var在块内被视为只读。见§ 8.13

  

在a中声明的局部变量   资源获取是只读的,   并且必须包含初始化程序。一个   如果出现编译时错误   embedded语句尝试修改   这些局部变量(通过赋值   或者++和 - 运算符)或传递   它们作为ref或out参数。

但请注意,这仅适用于声明为using语句一部分的变量,以下是合法的(不是一个好主意):

var f2 = System.IO.File.OpenText("");
using (f2)
{
    f2 = null;
}

答案 2 :(得分:1)

一个原因可能是doSomthing可以使s引用另一个Form实例,而不是我们创建的实例。这可能会引入资源泄漏,因为using块会在来自方法的Dispose实例上调用Form,而不是在using块中创建的实例。