我們寫一個類時,有時候會在同一個類上添加很多事件,事件很多的話,是不 容易管理的,.NET提供的EventHandlerList可以輔助多個事件的管理,但不方便 的地方是,它不是類型安全的,缺少類型安全,多少用起來擔心會出錯。經過我的 一番改造,可以將系統提供的EventHandlerList通過泛型提供類型安全的管理。 泛型類EventHandlerList.cs的實現如下:
public sealed class EventHandlerList<T> : IDisposable { 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<T> listToAddFrom) { ListEntry currentListEntry = listToAddFrom.head; while (currentListEntry != null) { AddHandler(currentListEntry.m_key, currentListEntry.m_handler); currentListEntry = currentListEntry.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<EventType> Events = new EventHandlerList<EventType>(); 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 raiseEvent = Events[eventType] as EventHandler; if (raiseEvent != null) raiseEvent(this, args); } // 其它邏輯,在適當的時候調用RaiseEvent private enum EventType { None, ReceiveData, RefreshData, Error, Info, } }
用起來更方便,很難出錯。希望對大家有用。
查看本欄目