使用反射清除所有挂在事件上的delegate
在.net中,event是一个相当有用的特性,它让我们可以很轻松的实现回调。但是它也有着相当的不方便之处:一个event在声明它的class之外只能使用+=/-=操作符进行delegate的增减,无法一次删除所有挂在它上面的delegate。
程序规模小的时候还好办,一旦程序膨胀,想弄清到底在一个事件上挂了那些delegate还真是挺麻烦的事情。尤其是很多class都有事件,很多事件在不同的地方被挂钩。当确定一个对象不用的时候,你需要及时把它的事件上挂的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
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) 编辑 收藏 举报