views:

153

answers:

8

Hi, I am just wondering, I thought I cannot have variables with the same name:

int Test;
public void A(int Test)
{

}

Why this does compile? I know I can use this keyword but seems to me strange that as the method is in the scope of the class it allows me to declare the variable with the same name.

+1  A: 

You can and it will Shadow that Test field in your class. Basically, it is not possible to redeclare a variable only if a local variable of the same name is already decalared in the current scope. But in your case the one has class scope and the other method scope.

Morteza Manavi
+9  A: 

int Test; is not variable, but field. Local variables can have same name as fields. If you refer to name, local variable has preference. If you want to refer to field then use this.

Andrey
That is it, thank you. I did not know fields can have the same names as local variables.
Ptr
+1  A: 

It will allow you to do it since you have not accessed the Test variable in this code sample. You would have to reference the class variable Test as this.Test in the A method to remove the ambiguity. In general you shouldn't do this though, it is bad style. The recommended coding style is that member variables should be prefaced with an _, so now your code would read:

int _Test;
public void A(int Test)
{
}
pstrjds
Microsoft's own source code often uses this style.
JeffN825
+4  A: 

From the C# Language specification, section 3.7 - Scopes

The scope of a name is the region of program text within which it is possible to refer to the entity declared by the name without qualification of the name. Scopes can be nested, and an inner scope may redeclare the meaning of a name from an outer scope (this does not, however, remove the restriction imposed by §3.3 that within a nested block it is not possible to declare a local variable with the same name as a local variable in an enclosing block). The name from the outer scope is then said to be hidden in the region of program text covered by the inner scope, and access to the outer name is only possible by qualifying the name.

Svetlozar Angelov
+1  A: 

You can. The member variable (outside the method) must be referred to as this.Test within the scope of the method itself. Inside the method, Test will refer to the parameter.

JeffN825
+1  A: 

You can hide wider scopes in a lot of cases (but not as liberally as you can in some other C-style languages), and certainly can have a field and parameter of the same name (or a field and a local).

For one thing, if we didn't allow scope to hide wider scope, commonly used words would soon be banned by being in a wider scope.

For another, we can introduce something to a wider scope down the line, and even from another assembly. Say you didn't have int Test; above. Now imagine than this is in a class that derives from another, and in that someone adds public int Test;. What is meant to be done to deal with that.

It is certainly a good idea to avoid such name collisions, and conventions can help (lower-case start for locals, upper-case start for non-private members, underscore start for private has the advantage of complaining about the non-CLR compliant underscore if you temporarily make the private member public in an experiment and forget to set it back), but banning it outright would be unworkable.

Jon Hanna
+7  A: 

Those variables have different names!

The first variable's full name is really MyType.Test, while the second variable (the function paramter) is just Test.

Joel Coehoorn
In C#, only static variables are named by type. (In contrast to C++, where instance variables might need to be qualified by a base class name, but C# uses the `base` keyword and not the actual type name)
Ben Voigt
+1  A: 

There is often confusion on the part of C# developers between scope, declaration space, and lifetime.

The C# language specifically allows the case you describe be making a method body a different declaration space from the method body. This allows for cases such as:

class Foo
{
   private string name;
   public Foo( string name )
   {
       this.name = name;
   }
}

where selecting a better name for the parameter name would require developers to employ naming conventions (which some do anyway). The term scope, refers to the regions of program text where you may refer to a construct by it's unqualified name. It's important to realize that scopes may overlap - which is the case here.

LBushkin