.NET Framework 提供 EventHandlerList 管理多事件委派,但缺乏型別安全,鍵值為 object 易導致執行期錯誤。本文提供泛型版本 EventHandlerList<T>,編譯期保證鍵值型別正確,消除拼字錯誤風險。
public sealed class EventHandlerList : IDisposable
{
private ListEntry head;
public EventHandlerList() { }
// 索引子存取
public Delegate this[T key]
{
get
{
ListEntry e = Find(key);
return e == null ? null : e.m_handler;
}
set
{
ListEntry e = Find(key);
if (e != null) e.m_handler = value;
else head = new ListEntry(key, value, head);
}
}
// 新增處理器 (支援多播)
public void AddHandler(T key, Delegate value)
{
ListEntry e = Find(key);
if (e != null) e.m_handler = Delegate.Combine(e.m_handler, value);
else head = new ListEntry(key, value, head);
}
// 批次新增
public void AddHandlers(EventHandlerList listToAddFrom)
{
ListEntry current = listToAddFrom.head;
while (current != null)
{
AddHandler(current.m_key, current.m_handler);
current = current.m_next;
}
}
public void Dispose() { head = null; }
private ListEntry Find(T key)
{
ListEntry found = head;
while (found != null)
{
if (found.m_key.Equals(key)) break;
found = found.m_next;
}
return found;
}
public void RemoveHandler(T key, Delegate value)
{
ListEntry e = Find(key);
if (e != null) e.m_handler = Delegate.Remove(e.m_handler, value);
}
private sealed class ListEntry
{
internal ListEntry m_next;
internal T m_key;
internal Delegate m_handler;
public ListEntry(T key, Delegate handler, ListEntry next)
{
m_next = next; m_key = key; m_handler = handler;
}
}
}
public class DispatcherCore
{
readonly EventHandlerList Events = new EventHandlerList();
public event EventHandler OnReceiveData
{
add { Events.AddHandler(EventType.ReceiveData, value); }
remove { Events.RemoveHandler(EventType.ReceiveData, value); }
}
public event EventHandler OnRefreshData
{
add { Events.AddHandler(EventType.RefreshData, value); }
remove { Events.RemoveHandler(EventType.RefreshData, value); }
}
private void RaiseEvent(EventType eventType, EventArgs args)
{
var handler = Events[eventType] as EventHandler;
if (handler != null) handler(this, args);
}
private enum EventType
{
None, ReceiveData, RefreshData, Error, Info
}
}
| 特性 | 原版 EventHandlerList | 泛型 EventHandlerList<T> |
|---|---|---|
| 鍵值型別 | object | T (編譯期檢查) |
| 拼字錯誤 | 執行期發現 | 編譯期錯誤 |
| IntelliSense | 無提示 | 完整列舉提示 |
| 重構安全 | 高風險 | 重構自動更新 |
| 效能 | 基準 | 無額外開銷 |
RaiseEvent(T key, params object[] args) 便利方法IEnumerable> 支援列舉EventHandlerList<TKey, TDelegate> 雙泛型版本查看本欄目