首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 3.0 Lambda 表達式深度體驗:從匿名方法到函數式風格

     編輯:關於C語言

演進脈絡

版本特性語法範例
C# 1.0/1.1具名委派方法btn.Click += new EventHandler(Btn_Click);
C# 2.0匿名方法btn.Click += delegate { list.Add(txt.Text); };
C# 3.0Lambda 表達式btn.Click += (s, e) => list.Add(txt.Text);

Lambda 語法解析


// 參數 => 運算式/語句區塊
x => x + 1                    // 隱含型別,單一參數可省略括號
(int x) => x + 1              // 顯式型別
(x, y) => x * y               // 多參數
() => Console.WriteLine("Hi") // 無參數
x => { var t = x * 2; return t; } // 語句區塊,需 return

型別推論

Lambda 參數型別由上下文推論:


Func f1 = x => x + 1;          // 推論 x 為 int
Func f2 = (x, y) => x + y; // 推論 x, y 為 int

實戰範例:列表篩選


var list = new List { "AA", "ABC", "DEFG", "XYZ" };

// 匿名方法 (C# 2.0)
var even1 = list.FindAll(delegate(string s) { return s.Length % 2 == 0; });

// Lambda (C# 3.0) - 更簡潔
var even2 = list.FindAll(s => s.Length % 2 == 0);

// 多參數 Lambda 搭配擴充方法
var clothes = new Dictionary
{
    ["Jeans"] = 20, ["Shirts"] = 15, ["Pajamas"] = 9, ["Shoes"] = 9
};

var shortage = clothes.FilterBy((name, count) => name == "Shoes" && count < 10);
// shortage 為 { ["Shoes", 9] }

擴充方法實作 FilterBy


public delegate bool KeyValueFilter(K key, V value);

public static class Extensions
{
    public static Dictionary FilterBy(
        this Dictionary dict, KeyValueFilter filter)
    {
        var result = new Dictionary();
        foreach (var kvp in dict)
            if (filter(kvp.Key, kvp.Value))
                result.Add(kvp.Key, kvp.Value);
        return result;
    }
}

IL 層面:匿名方法與 Lambda 等價

編譯器將兩者都降級為編譯器產生的私有方法 + 委派快取。IL 碼幾乎相同,Lambda 只是語法糖,執行效能無差異。

進階用法

運算式樹


using System.Linq.Expressions;

Expression> expr = x => x > 5; // 編譯為 Expression Tree,而非 IL
// 可於執行時分析、修改、轉譯為 SQL (LINQ to SQL/EF 核心機制)

非同步 Lambda


Func> asyncLambda = async () => {
    await Task.Delay(100);
    return 42;
};

捉拿變數閉包


var multipliers = new List>();
for (int i = 0; i < 3; i++)
{
    int factor = i; // 每次迴圈新建變數,避免閉包陷阱
    multipliers.Add(x => x * factor);
}
// multipliers[0](10) = 0, [1](10) = 10, [2](10) = 20

最佳實務建議

  1. 優先使用 Lambda:簡潔、可讀、現代 C# 風格。
  2. 避免過度嵌套:複雜邏輯抽離為具名方法。
  3. 注意閉包陷阱:迴圈中捉拿變數請在區塊內宣告區域變數。
  4. 運算式樹 vs 委派:需動態分析/轉譯用 Expression<TDelegate>,單純執行用 Func/Action。

結語

Lambda 表達式是 C# 邁向函數式程式設計的關鍵一步,配合 LINQ、非同步程式設計、運算式樹,極大提升了程式碼表達力。從 delegate { } 到 () => { },不只是語法簡化,更是思維模式的升級。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved