The lifetime of a
using
local will extend to the end of the scope in which it is declared. Theusing
locals will then be disposed in the reverse order in which they are declared.
My question is: when is a using
local considered out-of-scope?
Is it necessarily at the end of the block?
Is it necessarily right after its last use in the block?
Or is it implementation-defined, so that it could be either, or even anywhere in-between?
In other words:
{
using var res = Res();
res.DoStuff();
somethingElse.DoWhatever();
res.DoMoreStuff();
// 100 more statements that have nothing to do with res
}
Is this always equivalent to this (1)?
{
using (var res = Res()) {
res.DoStuff();
somethingElse.DoWhatever();
res.DoMoreStuff();
// 100 more statements that have nothing to do with res
}
}
Or always to this (2)?
{
using (var res = Res()) {
res.DoStuff();
somethingElse.DoWhatever();
res.DoMoreStuff();
}
// 100 more statements that have nothing to do with res
}
Or is this an implementation detail?
Does the spec define this? What is such "scope" technically? If one of the above is always the case, is there a reason to prefer this behavior over the other? I'd assume (2) is better, but maybe I'm wrong.
I know it probably doesn't change much for high-level programming, but I'm curious.
Somewhat related: Does a using block guarantee that the object will not be disposed until the end of the block?
CodePudding user response:
This is what a Scope means according to the language spec:
The scope of a name is the region of program text within which it is possible to refer to the entity declared by the name without qualification of the name.
[...]
The scope of a local variable declared in a local_variable_declaration (§12.6.2) is the block in which the declaration occurs.
Note that a using
declaration is just the word using
added to a local variable declaration. According to the using declaration proposal,
The language will allow for
using
to be added to a local variable declaration.
Therefore, your using
declaration is equivalent to
{
using (var res = Res()) {
res.DoStuff();
somethingElse.DoWhatever();
res.DoMoreStuff();
// 100 more statements that have nothing to do with res
}
}
The outermost { ... }
denotes a Block.
CodePudding user response:
In the .NET Blog in Do more with patterns in C# 8.0 we can read:
Using declarations are simply local variable declarations with a using keyword in front, and their contents are disposed at the end of the current statement block.
And then we can see:
static void Main(string[] args)
{
using var options = Parse(args);
if (options["verbose"]) { WriteLine("Logging..."); }
} // options disposed here
CodePudding user response:
Also, about
The
using
locals will then be disposed in the reverse order in which they are declared.
using (var v1 = Class1()) // disposed third
using (var v2 = Class2()) // disposed second
using (var v3 = Class3()) // disposed first
{
. . . .
}