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

    技术2022-05-11  28

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

    2007-03-23 13:00 by iceboundrock, 2851 visits, 网摘, 收藏, 编辑 在.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 


    最新回复(0)