變量作用域是一個讓很多初學者很容易混淆的一個概念。
變量的作用域是可以訪問該變量的代碼區域。一般情況下,確定作用域遵循以下規則:
只要類在某個作用域中,其字段也(也稱成員變量)也在該作用域內。
- 局部變量存在於表示聲明該變量的塊語句或方法結束的右花括號({})之前的作用域內。(請認真解讀讀透這句話)
- 在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; } } }