Why using variable treated as readonly? It is c# language specification or managed languages specification? It is because c# is a .net language? Thanks in advance.

Note: using variable is variable that appears in using statement

sample code:

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

we cant change value of a using variable in using block. the code will raise an error.

Note : i dont want you discuss about readonly keyword.

有帮助吗?

解决方案

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:

var form = new Form1();
using (form) {
    form = null;
}

works, but

using (var form = new Form1()) {
    form = null;
}

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

using (var something = new Foo()) {
   something = /* whatever */
}

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 reassigned something 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:

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.

In other words:

var form = new Form1();
using (form) {
    form = null;
}

works, because this is expanded to

var form = new Form1();
var invisibleThing = form;
try {
   form = null;
} finally {
    if (invisibleThing != null) ((IDisposable)invisibleThing).Dispose();
}

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

其他提示

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.

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 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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top