C# is not actually just a nicer version of Java

This is part one in what I feel certain will be a long-running series.

Most of the time I feel like C# is a better version of Java, but some language choices strike me as utterly foreign. For example, variable scope and declaration space are not the same thing! This means that you cannot reuse a variable with the same name as another one inside the same declaration space (like a method), even if those two separate declarations are in different scopes. This stack overflow question asks if it’s just nanny-state compilerism, and the very snarky top answer acts like it’s not completely counter-intuitive that this should be an error, rather than a warning. Here’s an example of the issue, reproduced from the stack overflow question:

for (int i = 0; i < 10; i++)
{
    Foo();
}
for (int i = 0; i < 10; i++) // Works just fine!
{
    Bar();
}

-----------------------------------------

for (int i = 0; i < 10; i++)
{
    Foo();
}
i = 10 // Error: The name 'i' does not exist in the current context

-----------------------------------------

for (int i = 0; i < 10; i++)
{
    Foo();
}
int i = 10; // Error: A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'child' scope to denote something else

-----------------------------------------

The top code fragment runs fine in both C# and Java. The middle one is a compile error in C# and Java. The bottom code compiles and runs fine in Java, since the first i is lexically scoped to the loop block. In C# it gives you the error in the comment. Gleaned from around the web, the justification for this being a compiler error appears to go something like this:

Look at it this way. It should always be legal to move the declaration of a variable UP in the source code so long as you keep it in the same block, right? If we did it the way you suggest, then that would sometimes be legal and sometimes be illegal!

My response: so? It's an imperative language. Yes, the order of declaration of members in a class is order independent, but the order of statements in a block is the program. No one expects to be able to arbitrarily move chunks of code up and down the page without changing the behavior.

In short: this absolutely is nanny-state compilerism. If I want to reuse a name in an independent scope, let me do it! You're going to end up with a lot of vector2s otherwise.

Leave a Reply