Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
661 views
in Technique[技术] by (71.8m points)

c# - Why is a variable declared in a using statement treated as readonly?

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...