+=/-=,不可直接調用/賦值EventArgspublic delegate void MyHandler1(object sender, MyEventArgs e);
public delegate void MyHandler2(object sender, MyEventArgs e);
public class MyEventArgs : EventArgs
{
public string Message { get; set; }
}
class Publisher
{
public event MyHandler1 Event1;
public event MyHandler2 Event2;
protected virtual void OnEvent1(MyEventArgs e)
{
Event1?.Invoke(this, e); // C# 6.0 null 條件運算子
}
protected virtual void OnEvent2(MyEventArgs e)
{
Event2?.Invoke(this, e);
}
public void TriggerEvents()
{
OnEvent1(new MyEventArgs { Message = "Event 1 fired" });
OnEvent2(new MyEventArgs { Message = "Event 2 fired" });
}
}
class Subscriber
{
public Subscriber(Publisher pub)
{
pub.Event1 += OnEvent1Received;
pub.Event2 += OnEvent2Received;
}
void OnEvent1Received(object sender, MyEventArgs e)
=> Console.WriteLine($"Handler1: {e.Message}");
void OnEvent2Received(object sender, MyEventArgs e)
=> Console.WriteLine($"Handler2: {e.Message}");
}
class Program
{
static void Main()
{
Publisher pub = new Publisher();
Subscriber sub = new Subscriber(pub);
pub.TriggerEvents();
}
}
.NET 2.0+ 內建泛型委派,無需自訂委派型別:
public class Publisher
{
public event EventHandler MyEvent;
protected virtual void OnMyEvent(MyEventArgs e)
=> MyEvent?.Invoke(this, e);
}
private EventHandler _myEvent;
public event EventHandler MyEvent
{
add
{
lock (_lock) _myEvent += value; // 執行緒安全註冊
}
remove
{
lock (_lock) _myEvent -= value;
}
}
防止訂閱者未解除註冊導致記憶體洩漏,使用 WeakReference 或 WeakEventManager (WPF)。
public event Func
Clicked、Saved、LoadingCompletedEventArgs 結尾protected virtual OnXxx 方法供衍生類擴展?.Invoke 簡化 null 檢查IDisposable 時在 Dispose 中解除所有事件註冊EventHandler<T> 替代自訂委派| 錯誤 | 後果 | 修正 |
|---|---|---|
直接賦值 evt = handler | 覆蓋其他訂閱者 | 使用 += |
外部直接調用 evt() | 破壞封裝 | 事件只能在類別內部觸發 |
| 未解除註冊 | 記憶體洩漏 | 在 Dispose/Unload 中 -= |
| 靜態事件持有實例參考 | 根引用導致 GC 無法回收 | 用弱事件或及時清理 |