如何取消订阅C#中特定类的事件的所有处理程序?

Nat*_*ith 33 .net c# events

基本前提:

我有一个房间,当一个阿凡达"进入"房间内的所有头像时,它会发布一个事件.当阿凡达离开房间时,我希望它删除该房间的所有订阅.

在将"阿凡达"添加到新房间并订阅新房间的活动之前,我怎样才能最好地取消订阅房间中所有活动的阿凡达?

代码如下:

class Room
{
   public event EventHandler<EnterRoomEventArgs> AvatarEntersRoom;
   public event EvnetHandler<LeaveRoomEventArgs> AvatarLeavesRoom;
   public event EventHandler<AnotherOfManyEventArgs> AnotherOfManayAvatarEvents;


   public void AddPlayer(Avatar theAvatar)
   {
      AvatarEntersRoom(this, new EnterRoomEventArgs()); 

      AvatarEntersRoom += new EventHandler<EnterRoomEventArgs>(theAvatar.HandleAvatarEntersRoom);

      AvatarLeavesRoom += new EventHandler<EnterRoomEventArgs>(theAvatar.HandleAvatarEntersRoom);

      AnotherOfManayAvatarEvents += new EventHandler<EnterRoomEventArgs>(theAvatar.HandleAvatarEntersRoom);          

   }

}

class Avatar
{
   public void HandleAvatarEntersRoom(object sender, EnterRoomEventArgs e)
   {
       Log.Write("avatar has entered the room");
   }

   public void HandleAvatarLeaveRoom(object sender, LeaveRoomEventArgs e)
   {
       Log.Write("avatar has left room");
   }

   public void HandleAnotherOfManayAvatarEvents(object sender, AnotherOfManyEventArgs e)
   {
       Log.Write("another avatar event has occurred");
   }
}
Run Code Online (Sandbox Code Playgroud)

Cha*_*ana 51

每个委托都有一个名为的方法GetInvocationList(),它返回已注册的所有实际委托.因此,假设委托类型(或事件)名为say MyDelegate,并且处理程序实例变量已命名myDlgHandler,您可以编写:

Delegate[] clientList = myDlgHandler.GetInvocationList();
foreach (var d in clientList)
       myDlgHandler -= (d as MyDelegate);
Run Code Online (Sandbox Code Playgroud)

覆盖它可能为null的情况,

 if(myDlgHandler != null)
  foreach (var d in myDlgHandler.GetInvocationList())
       myDlgHandler -= (d as MyDelegate);
Run Code Online (Sandbox Code Playgroud)

  • 您可能还想检查myDlgHandler!= null (6认同)
  • _"你想要的任何标准"_ - 你错过了重点.您要求获益,但不要证明.无论你有什么标准,你所给出的例子都不会以任何方式加强对这些代表的删除.随意演示,但无论你提出什么样的演示,都会有一个更简单的版本,不涉及调用`GetInvocationList()`._"不,它不会,它将是一个空委托"_ - "空委托"是"null".试试吧. (3认同)
  • 最新的表单实际上可能会崩溃.如果`myDlgHandler`为null,则`foreach`将计算为`foreach(var d in null)`,这将抛出`NullReferenceException`. (2认同)

Luk*_*uke 5

完成此操作的最简单方法可能是将头像的所有订阅事件存储在ArrayList事件的委托中。

当化身离开房间时,只需循环执行标准删除 ( ) 的代表列表即可-=