使用反射清除所有挂在事件上的delegate
2007-03-23 13:00
316 查看
在.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
程序规模小的时候还好办,一旦程序膨胀,想弄清到底在一个事件上挂了那些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
相关文章推荐
- 使用反射清除所有挂在事件上的delegate
- 使用反射清除所有挂在事件上的delegate
- 清除一个对象所有事件所挂钩的delegate
- 使用批处理for命令清除事件查看器所有Windows EventLog日志
- Qt使用一个事件队列对所有发出的事件进行维护(QObject的event()函数相当于dispatch函数),用EventLabel 继承QLabel作为例子(简单明了) good
- Java反射学习-使用反射修改一个类中的所有String类型的成员变量的值
- .NET/C#如何使用反射注册事件详解
- 使用反射移除指定对象的未知的事件的调用委托列表辅助类
- 使用WTL的消息反射封装CEdit实现监听控件文本改变事件
- 使用ASP .NET察看和清除你的事件日志
- 使用反射让Spinner选择同一选项时触发onItemSelected事件
- 利用java的反射机制得到界面类的所有可以增加的事件列表
- 使用C#得到局域网内所有主机名,IP地址,MAC地址,使用C# 实现查看所有系统事件
- c#事件处理中事件信息EventArgs的使用和类型内部事件委托delegate的调用
- EventBus源码分析(三):post方法发布事件【获取事件的所有订阅者,反射调用订阅者事件处理方法】(2.4版本)
- 使用反射取出实例挂勾的事件列表
- jquery插件select2的所有事件,包括清除,删除,打开等
- Unity3D技巧在Unity中使用事件/委托机制(event/delegate)进行GameObject之间的通信
- jQuery事件 delegate()使用方法介绍