在 C# 中,continue 語句會使 for 循環直接跳到迭代的結束位置。當 if 條件為 true 時,程式會略過 WriteLine 呼叫,直接跳轉到循環尾部(標籤 IL_0010),然後執行變數 V_0 的遞增操作。
goto 在 C# 中被視為不良實踐,但在 IL 層級,它與 break、continue 一樣,都被編譯為無條件分支指令 br。以下範例展示簡單的 goto 如何直接對應到 br.s:
// C# 代碼
public class zzz {
public static void Main() {
goto aa;
aa: ;
}
}
// 對應 IL
.method public hidebysig static void vijay() il managed {
.entrypoint
br.s IL_0002
IL_0002: ret
}
這揭示了一個有趣的事實:高階語言中被避諱的 goto,在 IL 中卻是實現 if、循環等控制結構的基石。
觀察一個簡單的 for 循環:
// C# 代碼
public class zzz {
public static void Main() {
int j;
for (int i = 1; i <= 2; i++)
System.Console.Write(i);
}
}
編譯後的 IL 顯示:
V_0、V_1 分別對應 i、j。i=1 後,以 br.s IL_000e 無條件跳轉到條件檢查處。IL_000e 將 i 與 2 比較(ble.s),若小於等於則跳回循環體 IL_0004。i,然後 i++,再回到條件檢查。.method public hidebysig static void vijay() il managed {
.entrypoint
.locals (int32 V_0,int32 V_1)
ldc.i4.1
stloc.1
br.s IL_000e
IL_0004: ldloc.1
call void [mscorlib]System.Console::Write(int32)
ldloc.1
ldc.i4.1
add
stloc.1
IL_000e: ldloc.1
ldc.i4.2
ble.s IL_0004
ret
}
輸出結果為 12。
C# 中 for 循環裡宣告的 i 僅在循環內可見,作用域受限。但轉換到 IL 時,所有區域變數(V_0、V_1)在方法層級皆可見,作用域相同。這是因為 IL 本身不具備區塊級作用域的概念,作用域管理由 C# 編譯器在編譯期強制執行。