標籤:
前面已經展示了一些在方法內部建立變數的例子。變數從定義了它的語句開始存在,同一個方法內的後續語句可以使用該變數。換言之,變數只能在建立了之後才能使用。方法執行完畢後,變數也會徹底消失。
假如一個變數能在程式中的一個特定位置使用,就說明該變數具有那個位置的範圍。也就是說,一個變數的範圍(scope)是指能夠使用該變數的程式地區。範圍既作用於方法,也作用於變數。一個標識符(不管它代表變數還是代表方法)的範圍是從聲明明該標識符的那個位置開始的。
定義局部範圍
界定方法主體的起始與結束大括弧建立了一個範圍。方法主體中聲明的任何變數都具有那個方法的範圍;一旦方法結束,它們也會消失,而且只能由那個方法內部執行的代碼來訪問。這些變數稱為局部變數(local variable),因為它們局限於聲明它們的那個方法,不能在其他任何方法的範圍中使用。換言之,你不能使用局部變數在不同的方法之間共用資訊。例如:
class Example
{
void firstMethod()
{
int myVar;
...
}
void anotherMethod()
{
myVar = 42; // 錯誤 – 變數越界
...
}
}
上述代碼將編譯失敗,因為anotherMethod方法試圖使用一個越界的myVar變數。該變數只能由firstMethod方法中的語句使用。
定義類範圍
界定類主體的起始和結束大括弧也建立了一個範圍。在類主體中(但不在一個方法中)聲明的任何變數都具有那個類的範圍。在C#術語中,開發人員使用欄位(field)一詞來描述由一個類定義的變數。和局部變數不同,你可以使用欄位在不同的方法之間共用資訊。 例如:
class Example
{
void firstMethod()
{
myField = 42; // ok
...
}
void anotherMethod()
{
myField = 42; // ok
...
}
int myField = 0;
}
變數myField是在類的內部以及firstMethod和anotherMethod方法的外部定義的。所以,myField具有類的範圍,可由類中的所有方法使用。
這個例子中還需要注意另一點。在一個方法中,必須在使用一個變數前聲明它。但欄位稍有不同,一個方法能在定義一個欄位的語句之前使用那個欄位——在這種情況下,編譯器將為你打點一切!
重載方法
如果兩個標識符同名,而且在同一個範圍中聲明,就可以說它們被重載(overloaded)。通常,重載的標識符屬於一個程式bug,會在編譯時間被捕捉到並報錯。例如,假定你在同一個方法中聲明了兩個同名的局部變數,就會獲得一個編譯時間錯誤。類似地,假如在同一個類中聲明了同名的兩個欄位,或者在同一個類中聲明了兩個完全一樣的方法,就會獲得一個編譯時間錯誤。這個事實表面上似乎不值一提,因為一切都會被報告為編譯時間錯誤。然而,你確實能通過一種方式來重載標識符,而且這種重載不僅是有用的,而且是重要的。
以Console類中的WriteLine方法為例,前面已經使用該方法向螢幕輸出一個字串。然而,在“代碼和文字編輯器”視窗中輸入WriteLine時,會自動彈出一個“智能感知”列表,其中列出了19個不同的版本!WriteLine方法的每個版本都擷取一套不同的參數。一個實現不擷取任何參數,只是輸出一個空行;另一個實現則擷取一個bool參數,並輸出它的值的字串形式(true或false);還有一個實現擷取一個小數值,並以字串的形式輸出它;等。程式編譯時間,編譯器會檢查所傳遞的實參的類型,然後調用參數集與之匹配的一個方法版本。下面是一個例子:
static void Main()
{
Console.WriteLine("The answer is ");
Console.WriteLine(42);
}
如果需要針對不同的資料類型執行相同的操作,重載就是一項十分有用的技術。如果不同的實現有不同的參數集,就可以考慮重載一個方法。換言之,每個版本都具有相同的方法名,但具有不同的參數數量或者不同的參數類型。利用這個功能,在調用一個方法時,可以提供一個以逗號分隔的實參列表,而編譯器將根據這些實參的數量和類型,選擇其中的一個匹配的重載版本。但要注意,雖然可以重載一個方法的參數,但不能重載方法的傳回型別。也就是說,不能聲明只是傳回型別有區別的兩個同名方法(編譯器雖然比較聰明,但還不至於聰明到那種程度)。
C# 運用範圍