Question on C# local variables scope
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 se开发者_运维技巧ems 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.
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.
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
.
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.
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)
{
}
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.
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.
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.
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.
精彩评论