变量的作用域是可以访问该变量的代码区域。一般情况下,确定作用域遵循以下规则:
1.只要类在某个作用域内,其字段(也称为成员变量)也在该作用域内(这句话可以简单的理解为,类中定义的字段可以在类中的任意地方被访问到)。
2.局部变量存在于表示声明该变量的块语句或方法结束的有花括号之前的作用域内。(注意:局部变量的作用域是定义该变量的语句块或方法的左右花括号之间的区域,而不是从定义该变量的语句开始到定义该变量的语句块或方法的右括号之间的区域,这个是我之前犯的一个错误。可以参考下边的例 2-4 )
3.在for、while或类似语句中声明的局部变量存在于该循环体内。
- 只要类在某个作用域内,其字段(也称为成员变量)也在该作用域内(这句话可以简单的理解为,类中定义的字段可以在类中的任意地方被访问到)。
- 局部变量存在于表示声明该变量的块语句或方法结束的右花括号之前的作用域内。
- 在for、while或类似语句中声明的局部变量存在于该循环体内。
下面,我们通过代码对上边3条规则进行解释:
1 class Person
2 {
3 //定义在类中的变量,称为类的字段或成员变量
4 string name = "CS";
5 int age = 20;
6
7 public void ShowPersonalInfo()
8 {
9 //定义在方法中的变量,此处的变量i,称为局部变量
10 for (int i = 0; i < 5; i++)
11 {
12 Console.WriteLine("My name is " + name);
13 }
14 for (int i = 0; i < 5; i++)
15 {
16 Console.WriteLine(i.ToString());
17 }
18 //定义局部变量times
19 int times = 0;
20 while (times < 5)
21 {
22 Console.WriteLine("I'm {0} years old.", age);
23 times++;
24 }
25 Console.WriteLine(times + ":" + "My name is {0},I'm {1} years old !", name, age);
26 }
27 }
通过上面的代码可以看出,Person类中name、age两个字段,以及局部变量times、i的作用域如下图所示:
图 2‑3 各变量的作用域
局部变量的作用域冲突
在大型的程序中,在不同部分为不同的变量使用相同的变量名很常见。只要变量的作用域是程序的不同部分,就不会有问题,也不会产生多义性。但要注意,同名的局部变量不能在同一作用域内声明两次。
错误尝试:下面这几种情况都是局部变量作用域发生冲突的情况
例 2-2:
1 public void ShowPersonalInfo()
2 {
3 int variable = 20;
4 for (int i = 0; i < 5; i++)
5 {
6 Console.WriteLine("My name is {0},I'm {1} years old !", name, age);
7 }
8 int variable = 30;
9 }
由于两个同名的局部变量variable的作用域一样,所以可以看到如下错误提示:
图 2‑4 局部变量的作用域及错误提示
例 2-3:
1 public void ShowPersonalInfo()
2 {
3 int i = 20;
4 for (int i = 0; i < 5; i++)
5 {
6 Console.WriteLine("My name is {0},I'm {1} years old !", name, age);
7 }
8 }
由于两个同名局部变量i的作用域存在包含关系,所以可以看到以下错误提示:
图 2‑5 局部变量的作用域及错误提示
例 2-4:
1 public void ShowPersonalInfo()
2 {
3 for (int i = 0; i < 5; i++)
4 {
5 Console.WriteLine("My name is {0},I'm {1} years old !", name, age);
6 }
7 int i = 20;
8 }
图 2‑6 局部变量的作用域及错误提示
字段和局部变量的作用域冲突
某些情况下,可以区分名称相同、作用域相同的变量。C#在变量之间有一个基本的区分,它把在类型级别声明的变量看作字段,而把方法中声明的变量看做局部变量。
例 2-5:
1 class Person
2 {
3 //定义在类中的变量,称为类的字段或成员变量
4 string name = "CS";
5 int age = 20;
6
7 public void ShowPersonalInfo()
8 {
9 //定义名称相同的局部变量
10 int age = 30;
11 string name = "CS2";
12 //局部变量隐藏了同名字段的值,此处的输出结果是”My name is CS2,I'm 30 years old !"
13 Console.WriteLine("My name is {0},I'm {1} years old !", name, age);
14 }
15 }
虽然同名变量的作用域存在包含关系,但是由于一个是字段,一个是局部变量,所以上述代码是没有问题的。