我正在使用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。
完成並完成...你真棒謝謝! – peter9464