我正在使用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。
答案 0 :(得分:1)
您需要将事件更改为EventHandler
类型
你不应该自己制作代表类型。
要传递其他数据,请使用EventHandler<T>
。