类型安全的EventHandlerList

我们写一个类时,有时候会在同一个类上添加很多事件,事件很多的话,是不容易管理的,.NET提供的EventHandlerList可以辅助多个事件的管理,但不方便的地方是,它不是类型安全的,缺少类型安全,多少用起来担心会出错。经过我的一番改造,可以将系统提供的EventHandlerList通过泛型提供类型安全的管理。泛型类EventHandlerList.cs的实现如下:

 1 public sealed class EventHandlerList<T> : IDisposable 
 2     { 
 3         ListEntry head;
 4 
 5         public EventHandlerList() 
 6         { }
 7 
 8         public Delegate this[T key]
 9         {
10             get{ 
11                 ListEntry e = Find(key);
12                 return e == null ? null : e.m_handler;
13             }
14             set{
15                 ListEntry e = Find(key);
16                 if (e != null){
17                     e.m_handler = value;
18                 } 
19                 else {
20                     head = new ListEntry(key, value, head);
21                 }
22             }
23         }
24 
25         public void AddHandler(T key, Delegate value) 
26         {
27             ListEntry e = Find(key); 
28             if (e != null) {
29                 e.m_handler = Delegate.Combine(e.m_handler, value);
30             }
31             else { 
32                 head = new ListEntry(key, value, head);
33             } 
34         } 
35 
36         public void AddHandlers(EventHandlerList<T> listToAddFrom) 
37         {
38             ListEntry currentListEntry = listToAddFrom.head;
39             while (currentListEntry != null) { 
40                 AddHandler(currentListEntry.m_key, currentListEntry.m_handler);
41                 currentListEntry = currentListEntry.m_next; 
42             } 
43         }
44  
45         public void Dispose() 
46         { 
47             head = null;
48         } 
49  
50         private ListEntry Find(T key) 
51         {
52             ListEntry found = head; 
53             while (found != null) {
54                 if (found.m_key.Equals(key)) {
55                     break;
56                 } 
57                 found = found.m_next;
58             } 
59             return found; 
60         }
61  
62         public void RemoveHandler(T key, Delegate value) 
63         {
64             ListEntry e = Find(key); 
65             if (e != null) {
66                 e.m_handler = Delegate.Remove(e.m_handler, value);
67             } 
68         }
69  
70         private sealed class ListEntry 
71         {
72             internal ListEntry m_next; 
73             internal T m_key; 
74             internal Delegate m_handler;
75  
76             public ListEntry(T key, Delegate handler, ListEntry next) 
77             {
78                 m_next = next;
79                 m_key = key;
80                 m_handler = handler; 
81             }
82         } 
83     }

有了它,我们就可以改变多个事件的使用方式,例子类似于下面这个。

 1 public class DispatcherCore
 2     {
 3         readonly EventHandlerList<EventType> Events = new EventHandlerList<EventType>();
 4 
 5         public event EventHandler OnReceiveData {
 6             add {
 7                 Events.AddHandler(EventType.ReceiveData, value);
 8             }
 9             remove {
10                 Events.RemoveHandler(EventType.ReceiveData, value);
11             }
12         }
13 
14         public event EventHandler OnRefreshData
15         {
16             add{
17                 Events.AddHandler(EventType.RefreshData, value);
18             }
19             remove{
20                 Events.RemoveHandler(EventType.RefreshData, value);
21             }
22         }
23 
24         private void RaiseEvent(EventType eventType, EventArgs args)
25         { 
26             var raiseEvent = Events[eventType] as EventHandler;
27 
28             if (raiseEvent != null)
29                 raiseEvent(this, args);
30         }
31 
32         // 其它逻辑,在适当的时候调用RaiseEvent
33 
34         private enum EventType
35         {
36             None,
37             ReceiveData,
38             RefreshData,
39             Error,
40             Info,
41         }
42     }

用起来更方便,很难出错。希望对大家有用。

 

posted on 2013-11-30 22:52  ProJKY  阅读(1709)  评论(1编辑  收藏  举报