【问题标题】:Why c# don't let to pass a using variable to a function as ref or out [duplicate]为什么 c# 不允许将 using 变量作为 ref 或 out 传递给函数 [重复]
【发布时间】:2011-08-25 10:53:09
【问题描述】:

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

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

这是我的代码:

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

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

【问题讨论】:

  • 方法doSomething(...)的签名是什么?您看到的错误是什么?
  • 嗯,接近选民?除非我完全弄错了,否则链接的问题与 using 块无关。
  • @Lightwing,当您删除代码时,我已回滚您的问题编辑,这会从问题和答案中删除上下文。如果您编辑问题,请不要删除重要内容,也不要修改问题。
  • 为什么使用只读变量?我觉得没必要
  • "为什么使用只读变量?" - 这是现有问题之上的另一个问题。请单独提问:stackoverflow.com/questions/ask

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


【解决方案1】:

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

但是,我怀疑你 需要 ref 这里;您已经将 reference 传递给表单,因为它是一个类。对于引用类型,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
}

因为它是同一个表单对象

【讨论】:

  • 为什么使用只读变量?
  • @LightWing 以避免混淆:即如果您更改变量的值会发生什么?什么得到处置? 原始值?还是 final 值? IMO 只有 original 值才有意义(实际上,您甚至不需要捕获它) - 那么为什么需要重新分配它呢?什么可能的场景使得在 using 语句中重新分配左值很有用?如果你发现这样的场景,只需使用 try/finally 代替。
  • 这是一个示例代码,我的代码真的没有这么简单。
  • @LightWing:这些是语言的规则。这个特殊的规则,将using 范围变量视为readonly,可以防止你在脚下开枪。如果您真的想更改变量,可以通过避免使用 using 块并将变量放置在显式 finally 块中来实现。但我严重怀疑您的设计的可维护性,特别是如果它更复杂!
  • 但任何规则都有一个或多个原因。
【解决方案2】:

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

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

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2010-10-14
      • 1970-01-01
      • 1970-01-01
      • 2020-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多