英文稱之為 Local Functions,是 C# 7.0 版本之後才新增的功能。
先前我們學過方法的呼叫,在方法程式區塊內,可以呼叫其他方法,規則如下:
- 同一類別內的方法:直接寫方法名稱並傳入參數即可呼叫;
- 跨類別方法:必須先建立目標類別的實例物件,而且目標方法要加上
public修飾詞。
從 C# 7.0 開始,允許在單一方法內部直接定義獨立函式,這類函式就叫做區域函式(本地函式):
- 隔離性:只能在包裹它的外層方法內呼叫,外部程式無法存取;
- 優點:相關程式邏輯集中在一起、可讀性更高,後續維護也更簡單;
- 宣告規則:和區域變數不同,區域函式可以在外層方法內任意位置宣告,不需要先宣告才能使用。
區域函式可以捕捉外層方法的區域變數,但作用域僅限於所屬的外層方法之中。
先補充一個基礎觀念:
函式內的區域變數是由上往下循序執行,一定要先宣告變數,之後才能使用,順序不能顛倒。
舉例來說,下面這段程式:hour 是寫在後面,不能在宣告之前就存取。
int GetHours()
{
Console.WriteLine(hour);
int hour = DateTime.Now.Hour;
return hour;
}Code language: C# (cs)
儘管 hour 的作用域涵蓋整個方法主體,依然不能先使用、後宣告。

程式會出現紅色波浪底線錯誤,錯誤訊息如上圖所示。
這和一般方法不同,下方的方法可以呼叫上方的方法。因為類別方法屬於類別成員,會記錄在 Method Table(方法表),呼叫時是查詢這張表格,並不是單純由上往下循序執行。

下面範例裡,上方的 Main 呼叫寫在後面的 GetHours,這跟剛才區域變數宣告使用規則完全不一樣。
class Program
{
static void Main()
{
Program program = new Program();
program.GetHours();
}
int GetHours()
{
int hour = DateTime.Now.Hour;
return hour;
}
}Code language: C# (cs)
回到主題,繼續介紹區域函式。
直接看範例:
class Program
{
static void Main()
{
Program program = new Program();
program.ZoomIn();
}
public void ZoomIn()
{
// 可以在區域函式宣告前就呼叫它
int results0 = ZoomIn5(10);
Console.WriteLine($"A: {results0}");
// 區域函式:將傳入數值 val 放大五倍後回傳
int ZoomIn5(int val)
{
return val * 5;
}
// 呼叫區域函式
int results = ZoomIn5(10);
Console.WriteLine($"B: {results}");
int results2 = ZoomIn5(5);
Console.WriteLine($"C: {results2}");
}
}
Code language: C# (cs)
區域函式的作用域限於所屬方法之內,不論程式寫在區域函式宣告的上方或是下方,都可以正常呼叫。
除此之外,區域函式名稱甚至可以和外層方法同名。
class Program
{
static void Main()
{
Program program = new Program();
program.ZoomIn5();
}
public void ZoomIn5()
{
// 可以在區域函式宣告前就呼叫它
int results0 = ZoomIn5(10);
Console.WriteLine($"A: {results0}");
// 區域函式:將傳入數值 val 放大五倍後回傳
int ZoomIn5(int val)
{
return val * 5;
}
// 呼叫區域函式
int results = ZoomIn5(10);
Console.WriteLine($"B: {results}");
int results2 = ZoomIn5(5);
Console.WriteLine($"C: {results2}");
}
}
Code language: C# (cs)
上面範例中,外層方法和內部區域函式都命名為 ZoomIn5。因為兩者作用域不同,不會發生命名衝突,但不建議大家這樣撰寫程式。
區域函式
Previous: void方法中的return
Next: 參數