Why does C# allow code blocks without a preceding statement (e.g. if
, else
, for
, while
)?
void Main()
{
I consider {}
as a statement that can contain several statements.
Consider an if statement that exists out of a boolean expression followed by one statement. This would work:
if (true) Console.Write("FooBar");
This would work as well:
if (true)
{
Console.Write("Foo");
Console.Write("Bar");
}
If I'm not mistaken this is called a block statement.
Since {}
can contain other statements it can also contain other {}
.
The scope of a variable is defined by it's parent {}
(block statement).
The point that I'm trying to make is that {}
is just a statement, so it doesn't require an if or whatever...
You asked "why" C# allows code blocks without preceeding statements. The question "why" could also be interpreted as "what would be possible benefits of this construct?"
Personally, I use statement-less code blocks in C# where readability is greatly improved for other developers, while keeping in mind that the code block limits the scope of local variables. For example, consider the following code snippet, which is a lot easier to read thanks to the additional code blocks:
OrgUnit world = new OrgUnit() { Name = "World" };
{
OrgUnit europe = new OrgUnit() { Name = "Europe" };
world.SubUnits.Add(europe);
{
OrgUnit germany = new OrgUnit() { Name = "Germany" };
europe.SubUnits.Add(germany);
//...etc.
}
}
//...commit structure to DB here
I'm aware that this could be solved more elegantly by using methods for each structure level. But then again, keep in mind that things like sample data seeders usually need to be quick.
So even though the code above is executed linearly, the code structure represents the "real-world" structure of the objects, thus making it easier for other developers to understand, maintain and extend.
The { ... }
has at least the side-effect of introducing a new scope for local variables.
I tend to use them in switch
statements to provide a different scope for each case and in this way allowing me to define local variable with the same name at closest possible location of their use and to also denote that they are only valid at the case level.