2012-08-26 263 views
1

我正在使用C#开发一个纸牌游戏项目。在这个游戏中,桌面上的牌需要订阅才会触发大量事件。但是,我需要卡片动态订阅和取消订阅事件,以便当前不活动的卡片不会响应正在触发的事件。动态订阅/取消订阅活动

我的解决方案是使用一个EventManager父类,每个事件有一个孩子。这些管理者中的每一个都会拥有以EventHandler作为参数的订阅/取消订阅方法。被调用时,方法将从分配给该管理器的事件中订阅/取消订阅提供的处理程序。

下面的代码是一个基本的控制台应用程序,它使用与我的纸牌游戏相同的设计模式,并且具有相同的问题。你可以直接将它粘贴到Visual Studio中,它会运行。

using System; 
using System.Collections.Generic; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var example = new ExampleCard(); 
      example.Subscribe(); 
      example.Events.FireEventOne(null, new EventArgs()); 
      example.UnSubscribe(); 
      example.Events.FireEventOne(null, new EventArgs()); 
      Console.ReadLine(); 
     } 
    } 

    public class EventContainer 
    { 
     public delegate void EventOne(Object sender, EventArgs r); 
     public event EventOne OnEventOne; 

     public EventContainer() 
     { 
      OnEventOne += Default_Handler; 
     } 

     public void Default_Handler(object sender, EventArgs e) 
     { 

     } 

     public void FireEventOne(object sender, EventArgs e) 
     { 
      OnEventOne(sender, e); 
     } 
    } 

    public class EventManager 
    { 
     protected EventContainer Events; 

     public EventManager(EventContainer events) 
     { 
      Events = events; 
     } 

     public virtual void Subscribe(EventHandler handler) 
     { 
     } 

     public virtual void Unsubscribe(EventHandler handler) 
     { 
     } 
    } 

    public class EventOneManager : EventManager 
    { 
     public EventOneManager(EventContainer events) 
      : base(events) 
     { 
     } 

     public override void Subscribe(EventHandler handler) 
     { 
      Events.OnEventOne += new EventContainer.EventOne(handler); 
     } 

     public override void Unsubscribe(EventHandler handler) 
     { 
      Events.OnEventOne -= new EventContainer.EventOne(handler); 
     } 
    } 

    public class ExampleCard 
    { 
     public EventContainer Events = new EventContainer(); 
     private readonly List<EventManager> _subscribedEvents = new List<EventManager>(); 

     public ExampleCard() 
     { 
      _subscribedEvents.Add(new EventOneManager(Events)); 
     } 

     public void Example_OnEventOneFired(object sender, EventArgs e) 
     { 
      Console.WriteLine("Event One was fired."); 
     } 

     public void Subscribe() 
     { 
      _subscribedEvents[0].Subscribe(Example_OnEventOneFired); 
     } 

     public void UnSubscribe() 
     { 
      _subscribedEvents[0].Unsubscribe(Example_OnEventOneFired); 
     } 
    } 
} 

EventOneManager.Subscribe()似乎工作,但EventOneManager.Unsubscribe()没有;在调用该方法后,示例卡仍然订阅了该事件,我无法弄清楚原因或解决方法。

有一两件事我想是去掉“新EventContainer.EventOne”呼叫使它看起来像这样:

public override void Unsubscribe(EventHandler handler) 
      { 
       Events.OnEventOne -= handler; 
      } 

但我得到这个错误:无法隐式转换类型“System.EventHandler”到“ConsoleApplication1。 EventContainer.EventOne“有什么建议?

另外我想能够使用自定义的EventArgs类,但我不知道如何传递一个通用的处理程序,它将与我正在使用的任何事件。我可以解决这个问题,但我更喜欢使用自定义的EventArgs。

回答

1

您需要将事件更改为EventHandler类型。
你不应该制作你自己的委托类型。

要传递更多数据,请使用EventHandler<T>

+0

完成并完成...你真棒谢谢! – peter9464