我正在用 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() 无效;调用该方法后,示例卡仍然订阅该事件,我不知道为什么或如何修复它。
我尝试过的一件事是删除“new EventContainer.EventOne”调用,使其看起来像这样:
public override void Unsubscribe(EventHandler handler)
{
Events.OnEventOne -= handler;
}
但我收到此错误:无法将类型“System.EventHandler”隐式转换为“ConsoleApplication1.EventContainer.EventOne”有什么建议吗?
此外,我希望能够使用自定义 EventArgs 类,但我不知道如何传入一个通用处理程序,该处理程序将与我正在使用的任何事件一起工作。我可以解决这个问题,但我更喜欢使用自定义 EventArgs。