335.C# 中使用局部函數而不用 Lambda

2024年2月6日 17点热度 0人点赞

摘要


在 C# 中,局部函數和 Lambda 表達式都可以用來定義在方法內部的小型函數。然而,它們之間存在一些關鍵的差異。局部函數是 C# 7.0 引入的新特性,它們可以用來創建臨時委托,而且在某些情況下比 Lambda 表達式更為高效和清晰。

正文


應用場景

局部函數相較於 Lambda 表達式更適用於以下場景:

  1. 性能敏感的代碼:局部函數通常比 Lambda 表達式更高效,因為它們不會捕獲外部變量時不會創建閉包。
  2. 遞歸調用:局部函數支持遞歸調用,而 Lambda 表達式則不那麼直觀。
  3. 復雜邏輯:對於包含多個步驟或變量的復雜邏輯,局部函數可以提供更好的可讀性。
  4. 避免閉包的副作用:局部函數可以避免由於捕獲外部變量而導致的不必要的堆分配。

示例 1: 使用局部函數進行簡單的操作

class Program
{
    public static int AddNumbers(int a, int b)
    {
        // 局部函數
        int AddLocal(int x, int y) => x   y;
        return AddLocal(a, b); // 使用局部函數
    }
    public static void Main()
    {
        int sum = AddNumbers(3, 4);
        Console.WriteLine(sum); // 輸出:7
    }
}

示例 2: 使用局部函數進行遞歸操作

class Program
{
    public static int Factorial(int n)
    {
        // 局部函數
        int FactorialLocal(int number)
        {
            if (number <= 1)
            {
                return 1;
            }
            return number * FactorialLocal(number - 1);
        }
        return FactorialLocal(n); // 使用局部函數
    }
    public static void Main()
    {
        int result = Factorial(5);
        Console.WriteLine(result); // 輸出:120
    }
}

示例 3: 使用局部函數避免閉包

public static IEnumerable<int> GetEvenNumbers(int[] numbers)
{
    bool IsEven(int number) => number % 2 == 0; // 局部函數
    foreach (var number in numbers)
    {
        if (IsEven(number)) // 使用局部函數
        {
            yield return number;
        }
    }
}
public static void Main()
{
    int[] numbers = { 1, 2, 3, 4, 5, 6 };
    foreach (var even in GetEvenNumbers(numbers))
    {
        Console.WriteLine(even); // 輸出偶數:2, 4, 6
    }
}

示例 4: 局部函數用於復雜邏輯

public static void ProcessData(int[] data)
{
    int GetMax() // 局部函數
    {
        int max = int.MinValue;
        foreach (var number in data)
        {
            if (number > max)
            {
                max = number;
            }
        }
        return max;
    }
    int GetMin() // 另一個局部函數
    {
        int min = int.MaxValue;
        foreach (var number in data)
        {
            if (number < min)
            {
                min = number;
            }
        }
        return min;
    }
    Console.WriteLine($"Max: {GetMax()}");
    Console.WriteLine($"Min: {GetMin()}");
}
public static void Main()
{
    int[] data = { -1, 2, 3, -4, 5, 6 };
    ProcessData(data); // 輸出最大值和最小值
}

結論

局部函數是 C# 中的一項強大功能,可用於創建臨時委托並在方法內部定義簡單或復雜的邏輯。相比於 Lambda 表達式,局部函數提供了更好的性能和遞歸支持,並且可以避免閉包導致的潛在副作用。在需要定義臨時委托的場景中,局部函數往往是更佳的選擇。通過上述示例,我們可以看到局部函數在不同場景下的應用,它們在提高代碼的可讀性和性能方面起到了關鍵作用