Just recently I found out you can do this in C#:
{
// google
string url = \"#\";
if ( value > 5 )
url = \"http://google.com\";
m
You could use {}
to to repurpose variable names (even for different types):
{
var foo = new SomeClass();
}
{
Bar foo = new Bar(); // impairs readability
}
However, repurposing variables in this way will confuse readability.
So instead of using "unsolicited" scope block without a preceding statement, in most cases the code should instead be refactored into separate functions accordingly.
Edit
IMO, any time there is the need to imperatively reset local mutable variable values or repurpose them for additional or alternative concerns is a sign of a smell. e.g. the original code can be refactored as:
menu.Add( value > 5
? new MenuItem("http://google.com")
: new MenuItem("#"));
menu.Add( value > 45
? new MenuItem("http://cheese.com")
: new MenuItem("#"));
Which I believe conveys the intention, without the risk of the #
fallback not being applied, and without the need for explicit local mutable variables to hold state.
(or new MenuItem(value > 45 ? "http://cheese.com" : "#")
, or create an overload of MenuItem
with a default of #
, or move the creation of MenuItem
into a factory method, etc.)
Edit
Re : Scope has no effect on lifespan
Scope can be used within a method to limit the lifespan of expensive objects
My initial post incorrectly stated that local scope could be used to influence the lifespan of objects. This is incorrect, for both DEBUG
and RELEASE
builds, and irrespective of whether the variable name is reallocated or not, as demonstrated by Jeppe's IL disassembly, and by these Unit tests here. Thanks to Jeppe for pointing this out. In addition, Lasse makes the point that even without explicitly going out of scope, variables no longer in use will be eligible for garbage collection in release builds.
TL;DR Although use of unsolicited scope may help convey the logical use of a variable scope to a human, doing so has no influence on whether the object becomes eligible for collection, within the same method.
i.e in the code below, scoping, and even re-purposing the variable foo
below has absolutely no effect on lifespan.
void MyMethod()
{
// Gratuituous braces:
{
var foo = new ExpensiveClass();
}
{
Bar foo = new Bar(); // Don't repurpose, it impairs readability!
}
Thread.Sleep(TimeSpan.FromSeconds(10));
GC.Collect();
GC.WaitForPendingFinalizers();
<-- Point "X"
}
At Point X:
DEBUG
build, neither of the foo
variables will have been collected despite the hacky attempts to entice the GC to do so.RELEASE
build, both foos would have been eligible for collection as soon as they aren't needed, irrespective of the scope. The timing of collection of course should be left to its own devices.