本課程相關內容在前幾堂課已經提過,不過這一節我們透過記憶體儲存機制,再次幫大家加深觀念。
本教學來自 foxdevelop.com,轉載請標明出處。
方法主體內可以巢狀放置其他程式碼區塊。
class Program
{
static void Main()
{
int age = 19;
{
int one = 23;
}
}
}
Code language: C# (cs)

程式碼區塊數量沒有上限,可以依序排列,也能多層巢狀,沒有層級限制。
class Program
{
static void Main()
{
int age = 19;
{
int one = 23;
{
int two = 45;
{
int three = 56;
}
}
}
}
}Code language: C# (cs)

要留意,子巢狀區塊上方像是 int xxxx = xxx; 這類陳述式,和巢狀區塊屬於平行陳述。

舉例來說,int age = 19; 和下方的巢狀程式碼區塊是兩個平行陳述,千萬不要誤以為這整段都是方法主體。
生命週期
來看一個範例
static void Main()
{
int a = 10;
{
int b = 20;
}
}Code language: C# (cs)
這個範例有兩個區域變數,外層的 a 位在 Main 函式最外側,b 則屬於內層巢狀程式碼區塊。
我們一步步執行,觀察堆疊記憶體的儲存方式。

第一步:只執行 int a = 10;,堆疊配置 a 的記憶體空間,值為 10;
第二步:進入內層區塊執行 int b = 20;,堆疊新增 b,堆疊由上至下順序:b、a;
第三步:內層程式碼區塊執行完畢,b 從堆疊移出,堆疊僅保留 a。
第四步:Main 方法執行結束,a 從堆疊移出,程式所有變數銷毀,程式執行完畢。
重點整理
在巢狀區塊內宣告的變數,生命週期從宣告位置開始,直到所屬程式碼區塊執行結束為止。
巢狀區塊執行完畢時,區塊內所有區域變數都會從堆疊移出並銷毀。
事實上,方法主體本身就是一個大型程式碼區塊。
有效範圍(作用域)
只要第一個變數的有效範圍仍然存在,無論巢狀多少層,都不能再次宣告同名的區域變數。
看範例
static void Main()
{
int a = 10;
{
int a = 20;
}
}Code language: C# (cs)

上面範例中,內層巢狀區塊的變數 a 和外層變數 a 名稱相同,此處會發生錯誤,無法通過編譯。
原因:外層 int a = 10; 的有效範圍是它所屬的大括號區塊內。在這個範圍裡,不允許出現同名變數。雖然 int a = 20; 寫在巢狀區塊中,但它仍然位於外層變數 a 的有效範圍內,造成名稱重複。編譯器偵測到重複宣告,直接標示紅色波浪錯誤。
就算第二個 a 更改變數型別,一樣不被允許。

同一個有效範圍內變數名稱必須唯一,和變數型別無關。

如圖所示,外層 a 的有效範圍為黃色區塊,內層 a 的有效範圍是綠色區塊。可以明顯看出外層範圍完整包含內層範圍,因此產生衝突。
解決方式就是把內層變數 a 換成其他名稱。

再看另一個範例
如果寫成下面這樣,還會發生衝突嗎?
class Program
{
static void Main()
{
int a = 10;
{
double b = 20;
}
{
double b = 30;
}
}
}Code language: C# (cs)
答案:不會。為什麼?雖然有兩個變數 b,但兩者有效範圍沒有重疊,因此不會報錯。上方的 b 僅屬於自身程式碼區塊,下方的 b 也僅屬於自身區塊,彼此互不衝突,可以正常編譯。參考圖示。

圖中以顏色標示兩個變數 b 各自的有效範圍。相信各位讀者現在已經理解。
巢狀程式碼區塊與作用域