C# 变量作用域
变量作用域是一个让很多初学者很容易混淆的一个概念。
变量的作用域是可以访问该变量的代码区域。一般情况下,确定作用域遵循以下规则:
只要类在某个作用域中,其字段也(也称成员变量)也在该作用域内。
- 局部变量存在于表示声明该变量的块语句或方法结束的右花括号({})之前的作用域内。(请认真解读读透这句话)
- 在for、while或类似语句中声明的局部变量存在于该循环体内。
- 局部变量的作用域冲突
大型程序在不同部分的变量使用相同的变量名很常见。只要变量的作用域是程序的不同部分,就不会有问题,就不会产生多义性。但请注意,同名的局部变量不能在统一作用域声明两次。例子如下:
public static int Main(){ int j=20; for(int i=0;i<10;i++){ int j=30; Console.WriteLine(j+i); } }
编译时提示的错误如下:
First.cs(24,10): error CS0136:
不能在此范围内声明名为“j”的局部变量,因为这样会使“j”具有不同的含义,而它已在“父级或当前”范围中表示其他内容了。
根据变量的作用域遵循的原则(局部变量存在于声明该变量的块语句或方法结束的右花括号({})之前的作用域内),第一个变量j是在for循环开始前定义的,它的作用域是Main()方法;第二个变量的作用域是在for循环;第一个变量j的作用域包含了第二个j的作用域。对编译器来说会存在歧义,因为编译器无法区分这两个变量,所以不允许声明第2个 变量。
2.字段和局部变量的作用域冲突
某些情况下,可以区分名称相同、作用域相同的两个标志符。此时编译器允许声明第2个变量。原因是C#在变量之间有一个基本的区分,他把类级别声明的变量看作字段(成员变量),而把方法中声明的变量看作局部变量。例子如下:
using System; namespace Wrox { class ScopeTest{ public int j=20; public static void Main(){ int j=30; Console.WriteLine(j); return; } } }
虽然在Main()方法中作用域中声明了两个变量,这段代码会正常编译。第一个j的作用域是这个ScropeTest类,第一个为Main()方法。此时,在Main()方法中声明的变量隐藏了同名的类级变量,所以这段代码,会显示数字为30。倘若要引用类级变量,可以使用语法object.fieldname.看如下代码:
using System; namespace Wrox { class ScopeTest{ public int j=20; public static void Main(){ int j=30; Console.WriteLine(j); ScopeTest obj=new ScopeTest(); Console.WriteLine("类级变量是:"+obj.j); return; } } }
可以选择将字段声明为 static。这使得调用方在任何时候都能使用字段,即使类没有任何实例。Demo如下:
using System; namespace Wrox { class ScopeTest{ static int j=20; public static void Main(){ int j=30; Console.WriteLine(j); // ScopeTest obj=new ScopeTest(); Console.WriteLine("类级变量是:"+ScopeTest.j); return; } } }