我们写一个类时有时候会在同一个类上添加很多事件事件很多的话是不容易管理的NET提供的EventHandlerList可以辅助多个事件的管理但不方便的地方是它不是类型安全的缺少类型安全多少用起来担心会出错经过我的一番改造可以将系统提供的EventHandlerList通过泛型提供类型安全的管理泛型类EventHandlerListcs的实现如下
public sealed class EventHandlerList<T> : IDisposable { ListEntry head; public EventHandlerList() { } public Delegate this[T key] { get{ ListEntry e = Find(key); return e == null ? null : em_handler; } set{ ListEntry e = Find(key); if (e != null){ em_handler = value; } else { head = new ListEntry(key value head); } } } public void AddHandler(T key Delegate value) { ListEntry e = Find(key); if (e != null) { em_handler = DelegateCombine(em_handler value); } else { head = new ListEntry(key value head); } } public void AddHandlers(EventHandlerList<T> listToAddFrom) { ListEntry currentListEntry = listToAddFromhead; while (currentListEntry != null) { AddHandler(currentListEntrym_key currentListEntrym_handler); currentListEntry = currentListEntrym_next; } } public void Dispose() { head = null; } private ListEntry Find(T key) { ListEntry found = head; while (found != null) { if (foundm_keyEquals(key)) { break; } found = foundm_next; } return found; } public void RemoveHandler(T key Delegate value) { ListEntry e = Find(key); if (e != null) { em_handler = DelegateRemove(em_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 { EventsAddHandler(EventTypeReceiveData value); } remove { EventsRemoveHandler(EventTypeReceiveData value); } } public event EventHandler OnRefreshData { add{ EventsAddHandler(EventTypeRefreshData value); } remove{ EventsRemoveHandler(EventTypeRefreshData 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 } }
用起来更方便很难出错希望对大家有用