zoukankan      html  css  js  c++  java
  • 类型安全的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     }

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

  • 相关阅读:
    要使用springtest来进行单元测试 否则将无法注入 applicationContext.xml
    关键词的重要性
    发卡可以以交叉方式佩戴来增强可爱性
    红毛类型
    oracle学习总结4
    对springMVC的简单理解
    理解RESTful架构
    项目移植过程中报:“Project facet Java version 1.7 is not supported.” 错误
    svn服务器的搭建
    oracle学习总结3
  • 原文地址:https://www.cnblogs.com/ProJKY/p/EventHandlerList.html
Copyright © 2011-2022 走看看