0

I created a c# test class like below, I intend to test what gonna happen if I created one variable twice in and out of scope. But to my surprise, it runs and outputs the value "inside".

This is an illegal way to multiple declare a same variable if I wrote this code snippet into Main() method, the compiler error would occur accordingly. But how come it can work in a separate class? Then how can we avoid making such mistakes?

    class Program
    {
        static void Main(string[] args)
        {                
            Test tst = new Test();
            tst.ScopeAlert();
            Console.ReadLine();
        }
    }

    public class Test
    {
        string scope = "outside";
        public void ScopeAlert()        
        {
            string scope = "inside";

            Console.WriteLine(scope);
        }
    }
Doctor Jones
  • 21,196
  • 13
  • 77
  • 99
cj9435042
  • 111
  • 3
  • 5
    Inside the `Test` class you declared a field called scope. To access it in your `ScopeAlert` method, you would write `this.scope`. You have also declared the local `scope` variable. There is nothing "illegal" about this. – zaitsman Jan 09 '19 at 03:31
  • 1
    I wholeheartedly concur with my learned colleague @zaitsman – BenKoshy Jan 09 '19 at 03:40

2 Answers2

9

First off, though you are correct that these are scopes, the better jargon to use in this specific situation is declaration space. There is a subtle difference. A declaration space is a region of code in which no two things may be declared to have the same name (except for overloaded methods). A scope is a region of text in which a particular name may be used without qualification. They are closely related but they are not the same thing.

The rules of C# are that declaration spaces for classes and locals are different, and allow the same name to be declared in both. However, nested declaration spaces for locals do not permit locals in inner spaces to shadow locals in outer spaces.

Your example is legal because the declaration spaces are not both local.

If we had local spaces:

void M()
{
  { int j = 1; }
  { int j = 2; }
}

That's legal because they do not overlap. But

void M()
{
  { int j = 1;  { int j = 2; } }
}

Is illegal because the spaces do overlap.

Consult the C# specification for more details.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
1

What you have is perfectly fine in C# and is allowed. If you need to access

string scope = "outside";

then need to use this.scope. More info on accessibility levels of variables like private, public, internal, protected, protected internal is here:

In C#, what is the difference between public, private, protected, and having no access modifier?

Also, you have a method:

public void ScopeAlert()        {
    string scope = "inside";

    Console.WriteLine(scope);
}

The variable defined with value "inside" can be accessed anywhere within the method. However, the following won't work:

public void ScopeAlert()        {
    while(true) 
    {
        string scope = "inside";
    }

    Console.WriteLine(scope);  // will give an error as scope is limited to {}.
}
Gauravsa
  • 6,330
  • 2
  • 21
  • 30