C# 從基礎到精通 — 第 5 講
透過委託、事件和 lambda 傳遞操作
該部落格上撰寫的文章是出於教學目的而創建的。 另外,文章中的資訊可能不正確,請謹慎。
可以直接呼叫方法,但稍後執行的操作本身也可以作為值傳遞。 C# 中的委託、事件和 lambda 表達了此流程。
代表
int Double(int value) => value * 2;
Func<int, int> operation = Double;
int result = operation(10);
Action<string> logger = message => Console.WriteLine(message);
logger("Battle started");
Func<int, int>是接收int並回傳int的action,Action是沒有回傳值的action。 呼叫程式碼不需要知道實際正在執行哪個方法。
事件
public sealed class Player
{
public event Action<int>? HealthChanged;
public int Health { get; private set; } = 100;
public void TakeDamage(int amount)
{
Health = Math.Max(0, Health - amount);
HealthChanged?.Invoke(Health);
}
}
player.HealthChanged += health => healthBar.SetValue(health);
事件通知有狀態物件發生變化並導致其他物件(例如 UI 或聲音)做出回應。 從外部只能訂閱和取消訂閱,不能隨意呼叫事件。
訂閱生命週期管理
void OnEnable()
{
player.HealthChanged += UpdateHealth;
}
void OnDisable()
{
player.HealthChanged -= UpdateHealth;
}
如果短壽命物件繼續訂閱長壽命物件的事件,則記憶體和呼叫可能會保留。 註冊地點和相應的發布地點必須一起確定。
拉姆達捕獲
int bonus = 5;
Func<int, int> addBonus = damage => damage + bonus;
如果 lambda 使用外部局部變量,則可以建立一個物件來儲存該值。 繼續在每幀重複的程式碼中建立捕獲 lambda 可能會導致不必要的分配。
委託是操作的類型,事件為更改通知建立邊界。 為了方便起見,用事件替換所有呼叫會導致追蹤執行順序變得困難,因此應該在需要鬆耦合的地方使用它。