November 18

Scope of Local Variables in C# and C++

2  comments

Consider the following code in C++:
This code actually compile and the output is the following:
The important thing to notice here is that in C++ is possible to declare a variable with the same name in a nested block.
In fact the standard documentation say:
“A name declared in a block is local to that block; it has block scope. Its potential scope begins at its point of declaration and ends at the end of its block. A variable declared at block scope is a local variable.”
In C# this is not possible. The following code does not compile:
In C# you cannot declare another local variable with the same name in the current block or in any nested blocks. In addition, the variable scope extends in both directions throughout its code block. 
Even the following code does not compile:
I would say that the restriction imposed by C# is good and avoid unexpected behaviours in some situations. It also encourages to use meaningful names for variables avoiding to reuse the same variable for different purposes.
However, the following C# code compiles:
This because the two blocks are not related to each others. They are not part of the same chain of nested blocks. This is good because there is a typical situation when you like to reuse the same variable name in loops. 
This code compiles:

Tags


You may also like

The best way to stay up to date with C# 10 features

My Technical Journey from my first program to Lead Software Engineer

Top 10 C# Developer News from Microsoft Build 2020

Agile Estimation

  • C++ seems more logical and consistent given that C# does allow a method variable to shadow a class field but I think that the C# behaviour is preferable for avoiding mistakes. I've hit a few bugs where class fields were accidentally redeclared in methods so I would like the compiler to prevent that too.

    e.g.
    class MyClass
    {
    int m_X = 10;
    public void Load()
    {
    int m_X = 20; // mistake, shadowed this.m_X!
    }
    public void Print()
    {
    Console.WriteLine(m_X);
    }
    }

  • C++ is consistent because simply allows everything. It always assume you know what you are doing. It is by design 🙂

    What you say about shadowing a class field is true. C# is permissive in some situations.

    I tried to change a little bit your code with this:

    class MyClass
    {
    int x = 10;

    public void Load()
    {
    x = 10;
    int x = 0;
    }

    public void Print()
    {
    Console.WriteLine(x);
    }
    }

    This code does not compile!!! 🙂

    You get the following error:

    Error 1 Cannot use local variable 'x' before it is declared. The declaration of the local variable hides the field 'ConsoleApplication.MyClass.x'.

    Anyway, ReSharper detects this and nobody stop you to set severity to "Error".

    This is one of the reason why some people like using underscores before the name of a field. However, I honestly don't like it. I use "this" only in constructors and generally I tend to avoid to use local variables with the same name of fields.

    Thanks for you comment. Very interesting

  • {"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

    Subscribe to our newsletter now!

    Get instant access to the Master C# 9 webinar to learn all the new exciting C# 9 features quickly.
    Get regular videos and news on C# and .NET and offers on products and services to master C#.

    We will collect, use and protect your data in accordance with our Privacy Policy.

    >