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() 无效;调用该方法后,示例卡仍然订阅该事件,我不知道为什么或如何修复它。

我尝试过的一件事是删除“new EventContainer.EventOne”调用,使其看起来像这样:

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

但我收到此错误:无法将类型“System.EventHandler”隐式转换为“ConsoleApplication1.EventContainer.EventOne”有什么建议吗?

此外,我希望能够使用自定义 EventArgs 类,但我不知道如何传入一个通用处理程序,该处理程序将与我正在使用的任何事件一起工作。我可以解决这个问题,但我更喜欢使用自定义 EventArgs。

4

1 回答 1

1

您需要将事件更改为 type EventHandler
您不应该创建自己的委托类型。

要传递其他数据,请使用EventHandler<T>.

于 2012-08-26T18:16:36.487 回答