本文假設讀者熟悉匿名方法。Lambda 表達式(λ運算式)不只是「字面縮短」,規模變化帶來質的轉變——如同實驗室燒杯現象不一定在大型工廠重現,程式碼簡潔度提升會改變開發模式。
public delegate bool SimpleMenuAction();
public class MenuItemA {
public readonly string Name;
public readonly SimpleMenuAction Action;
public MenuItemA(string name, SimpleMenuAction action) { ... }
}
private static MenuItemA[] MenuItems1 = {
new MenuItemA("選項1", 執行方法),
new MenuItemA("選項2", 執行方法),
new MenuItemA("選項3", 執行方法),
};
初步方案:在類別加 FromHour 整數欄位。
public class MenuItemB {
public readonly string Name;
public readonly SimpleMenuAction Action;
public readonly int FromHour; // 0 表示無限制
// ...
}
private static MenuItemB[] MenuItems2 = {
new MenuItemB("選項1", 執行方法, 0),
new MenuItemB("選項4", 執行方法, 19), // 19:00 後顯示
};
但此設計脆弱:若改為 19:30?需加結束時間?依星期判斷?每新增條件都要改類別結構,違反 YAGNI 原則(You Aren't Gonna Need It)。
public delegate bool SimpleMenuAvailability();
public class MenuItemC {
public readonly string Name;
public readonly SimpleMenuAction Action;
public readonly SimpleMenuAvailability IsAvailable; // 條件委派
// ...
}
private static MenuItemC[] MenuItems3 = {
new MenuItemC("選項1", 執行方法, delegate() { return true; }),
new MenuItemC("選項4", 執行方法, delegate() { return DateTime.Now.Hour >= 19; }),
};
大量 delegate() { return ...; } 樣板碼讓意圖模糊,若為「也許將來用得到」而預先寫入,屬於 YAGNI 反模式。
private static MenuItemC[] MenuItems4 = {
new MenuItemC("選項1", 執行方法, () => true),
new MenuItemC("選項4", 執行方法, () => DateTime.Now.Hour >= 19),
};
程式碼瞬間清爽,在不損害可讀性前提下為未來變更上保險。
幾天後需求改為「19:00~22:00 顯示」,僅修改單一 Lambda:
new MenuItemC("選項4", 執行方法,
() => DateTime.Now.Hour >= 19 && DateTime.Now.Hour < 22),
若用最初 MenuItemB 設計,需加欄位、改建構子、修改選單建構邏輯,工程量成倍增加。匿名方法與 Lambda 的長度差異,直接決定了是否願意採用彈性設計。