为什么在 using 语句中声明的变量被视为只读?
为什么 using 块中的变量 (myform) 被视为只读,并且当我尝试将其作为函数的引用传递时,编译器会引发错误。
示例代码:
using (Form myform = new Form)
{
myfunc(ref myform);
}
将使用变量作为 ref 传递给函数将引发错误。因此上面的代码会引发错误。
注意:“readonly”关键字与我的问题无关。
why variable (myform) in using block treated as read-only and the compiler raise an error when I try to pass it as a reference to a function.
sample code:
using (Form myform = new Form)
{
myfunc(ref myform);
}
passing using variable to a function as ref will raise an error. thus the code above will raise an error.
Note : 'readonly' keyword is unrelated to my question.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我现在正在查看一个(过时的?)规范 [1]。
15.13 规定您在资源获取部分声明的变量是只读的。也就是说:
有效,但
无效。
这回答了部分问题(即为什么?因为它是规范的一部分......),但我知道这并不是真正令人满意。但你为什么要这么做呢?
编辑:在思考这一点之后,让我为这条规则提供一个可能的解释:
你有
并且编译器允许这样做。现在,如果 Foo 需要大量非托管资源(也许这就是您首先想要使用
using
的原因)怎么办?在 using 块之后,您将无法再访问此引用。它没有被处理,因为您重新分配了某物
并且忘记自己处理它。您根本无法保证 GC 会运行。或者什么时候。您刚刚创建了一个被掩盖和隐藏的资源泄漏。最后一个,灵感来自 Henk 的 Eric Lippert 博客链接,该链接最终再次向我们抛出了规范:
换句话说:
有效,因为它被扩展为
所以在这种情况下,您对
using
引用没有影响的事实只是对您隐藏,并且与前一种情况完全相同。1:http://www.ecma-international.org/publications/standards/Ecma-334.htm
I'm looking at an (outdated?) spec [1] right now.
15.13 says that variables that you declare in the resource acquisition part are readonly. That is:
works, but
doesn't.
This answers part of the question (i.e. Why? Because it is part of the spec..), but I understand that this is not really satisfying. But why would you even want to do that?
Edit: After thinking about this, let me offer a possible explanation for this rule:
You have
and the compiler allows this. Now what if Foo needs a lot of unmanaged resources (maybe that's the reason you wanted to use
using
in the first place)? After the using block you have no way to access this reference anymore. It wasn't disposed, because you reassignedsomething
and forgot to handle it yourself. You don't have a guarantee that the GC runs, at all. Or when. You just created a resource leak that is obscured and hidden.A final one, inspired by Henk's link to Eric Lippert's blog, which again just ends up throwing the spec at us:
In other words:
works, because this is expanded to
So in this case the fact that you have no influence over the
using
reference is just hidden from you and is exactly like in the previous case.1:http://www.ecma-international.org/publications/standards/Ecma-334.htm
如果您的意思是在 using 块的开头实例化的变量,那么它是只读的,因为它需要在块的末尾进行处理。 using 块的要点是以可预测的方式销毁资源,而不是等待垃圾收集器完成其工作。
If you mean the variable instantiated at the start of a using block, then it's read only because it needs to be disposed at the end of the block. The point of a using block is to have a resource destroyed in a predictable way rather than waiting for the garbage collector to do it's job.
首先,在您的示例中,很可能没有理由使用
ref
修饰符。所以你问的是一个非常理论化的问题,它在实践中从来都不是问题。
带注释的C#3手册没有给出解释。
Eric Lippert 在一篇文章 关于(不是)using 语句中的装箱。
我自己的尝试:
编译器将受控变量设为只读因为它可以。让这个 var 可写会带来更多的麻烦,请参阅 Eric 的 Boxing 文章。请注意,类似的规则适用于
foreach()
中的封闭变量。基本上,写入这些变量永远没有用,因此编译器对它们进行最大程度的控制。First of all, in your example there is most likely no reason for the
ref
modifier.So you're asking a very theoretical question, it never is a problem in practice.
The annotated C#3 manual does not give an explanation.
Eric Lippert touches on the subject in a post about (not) Boxing in a using statement.
My own stab at it:
The compiler makes the controlled var readonly because it can. Leaving this var writeable would open up even more cans of worms, see the Boxing article from Eric. Note that a similar rule applies to the enclosed variable in a
foreach()
. Basically, writing to these vars would never be useful, so the compiler takes maximum control over them.readonly 是 C# 中的关键字。当您想要确保值在构造函数之外永远不会更改时,它非常有用。
当您向大型项目贡献代码并且担心同事可能会尝试更改不应更改的变量时,此关键字可能会很有帮助。
编辑:我很好奇为什么有人对我的回答投了反对票。谁投了反对票,你能告诉我我的答案哪里错了吗?谢谢。
readonly is a keyword in C#. It's useful when you want to ensure the value never changes outside a constructor.
This keyword could be helpful when you're contributing code to a large project and you're worried coworkers might try to change a variable that should never be altered.
Edit: I'm curious why someone downvoted my answer. Whoever downvoted can you please show my where my answer is wrong? Thanks.