NCindy

.net平台上的高性能网络程序开发框架

使用反射清除所有挂在事件上的delegate

在.net中,event是一个相当有用的特性,它让我们可以很轻松的实现回调。但是它也有着相当的不方便之处:一个event在声明它的class之外只能使用+=/-=操作符进行delegate的增减,无法一次删除所有挂在它上面的delegate。
程序规模小的时候还好办,一旦程序膨胀,想弄清到底在一个事件上挂了那些delegate还真是挺麻烦的事情。尤其是很多class都有事件,很多事件在不同的地方被挂钩。当确定一个对象不用的时候,你需要及时把它的事件上挂的delegate断开。
下面这个函数可以起到直接清空一个对象所有的事件的作用,还是老规矩,代码就不多解释了:
 1         /// <summary>
 2         /// 清除一个对象所有事件所挂钩的delegate
 3         /// </summary>
 4         /// <param name="objectHasEvents">有事件的对象</param>
 5         public static void ClearAllEvents(object objectHasEvents)
 6         {
 7             if (objectHasEvents == null)
 8             {
 9                 return;
10             }
11 
12             EventInfo[] events = objectHasEvents.GetType().GetEvents(
13                 BindingFlags.Public |
14                 BindingFlags.NonPublic |
15                 BindingFlags.Instance);
16 
17             if (events == null || events.Length < 1)
18             {
19                 return;
20             }
21 
22             for (int i = 0; i < events.Length; i++)
23             {
24                 try
25                 {
26                     EventInfo ei = events[i];
27 
28                     /********************************************************
29                      * class的每个event都对应了一个同名的private的delegate类
30                      * 型成员变量(这点可以用Reflector证实)。因为private成
31                      * 员变量无法在基类中进行修改,所以为了能够拿到base 
32                      * class中声明的事件,要从EventInfo的DeclaringType来获取
33                      * event对应的成员变量的FieldInfo并进行修改
34                      ********************************************************/
35                     FieldInfo fi =
36                         ei.DeclaringType.GetField(ei.Name,
37                                                   BindingFlags.NonPublic |
38                                                   BindingFlags.Instance);
39                     if (fi != null)
40                     {
41                         // 将event对应的字段设置成null即可清除所有挂钩在该event上的delegate
42                         fi.SetValue(objectHasEvents, null);
43                     }
44                 }
45                 catch
46                 {
47                 }
48             }
49         }
50 
51 

posted on 2007-03-23 13:00  iceboundrock  阅读(4155)  评论(12编辑  收藏  举报

导航