概念: 本地函數是一種嵌套在另一成員中的類型的方法。 僅能從其包含成員中調用它們。
下面是本地方法最簡單的一個demo:
public static int Show(){int c = NewMethod();?return c;static int NewMethod(){#region 測試int a = 3;int b = 9;int c = a + b;#endregionreturn c;}}
本地函數語法
?本地函數可使代碼意圖明確。 任何讀取代碼的人都可以看到,此方法不可調用,包含方法除外。 對于團隊項目,它們也使得其他開發人員無法直接從類或結構中的其他位置錯誤調用此方法。
本地方法使用注意事項:
1. 本地函數不能使用修飾符,因為都是私有的,包括訪問修飾符(如?private
?關鍵字)會生成編譯器錯誤 CS0106“修飾符‘private’對于此項無效”。
2. 本地函數,本地方法一般放在方法的結尾
private static string GetText(string path, string filename)
{var reader = File.OpenText($"{AppendPathSeparator(path)}{filename}");var text = reader.ReadToEnd();return text;string AppendPathSeparator(string filepath){return filepath.EndsWith(@"\") ? filepath : filepath + @"\";}
}
? ? ?本地函數與 Lambda 表達式
本地函數和?Lambda 非常相似。 但是,應該注意,從兩者中選用一種的時機和條件其實是存在差別的。
讓我們檢查一下階乘算法的本地函數實現和 lambda 表達式實現之間的差異。 下面是使用本地函數的版本:
public static int LocalFunctionFactorial(int n)
{
? ? return nthFactorial(n);
? ? int nthFactorial(int number) => number < 2?
? ? ? ? ? 1?
? ? ? ? : number * nthFactorial(number - 1);
}
public static int LambdaFactorial(int n)
{
? ? Func<int, int> nthFactorial = default(Func<int, int>);
? ? nthFactorial = number => number < 2
? ? ? ? ? 1
? ? ? ? : number * nthFactorial(number - 1);
? ? return nthFactorial(n);
}
明確賦值
Lambda 表達式是在運行時聲明和分配的對象。 若要使用 Lambda 表達式,需要對其進行明確賦值:必須聲明要分配給它的?Action
/Func
?變量,并為其分配 Lambda 表達式。 請注意,LambdaFactorial
?必須先聲明和初始化 Lambda 表達式?nthFactorial
,然后再對其進行定義。 否則,會導致分配前引用?nthFactorial
?時出現編譯時錯誤。
本地函數在編譯時定義。 由于未將它們分配給變量,因此可以從范圍內的任意代碼位置引用它們;在第一個示例?LocalFunctionFactorial
?中,我們可以在?return
?語句的上方或下方聲明本地函數,而不會觸發任何編譯器錯誤。
這些區別意味著使用本地函數創建遞歸算法會更輕松。 你可以聲明和定義一個調用自身的本地函數。 必須聲明 Lambda 表達式,賦給默認值,然后才能將其重新賦給引用相同 Lambda 表達式的主體。
int M()
{
? ? int y;
? ? LocalFunction();
? ? return y;
? ? void LocalFunction() => y = 0;
}
這段代碼定義了一個名為LocalFunction()的方法,該方法使用lambda表達式定義了一個局部函數,并將其實現設為將變量y的值設為0。
等于如下:
void LocalFunction()
{
? ? y = 0;
}
?實現詳細信息包括本地函數的閉包是作為?class
?還是?struct
?實現。 本地函數可能使用?struct
,而 lambda 將始終使用?class
。
雖然本地函數對 lambda 表達式可能有點冗余,但實際上它們的目的和用法都不一樣。 如果想要編寫僅從上下文或其他方法中調用的函數,則使用本地函數更高效。