这是我的代码:
static class MessageHandler<T> where T : Message
{
public delegate void MessageDelegate(T m);
private static MessageDelegate messageHandlers;
public static void Publish(T message)
{
messageHandlers(message);
}
public static void Subscribe(MessageDelegate messageHandler)
{
messageHandlers += messageHandler;
}
}
Message
只是一个其他类可以继承的空类。大多数Message
派生是具有相关属性的简单对象(这是针对游戏的,因此可能有一个 PlayerDamagedMessage
,其属性为损坏和袭击者。)
基本上,在 Player
当他们受到攻击时,他们会发布一个PlayerDamagedMessage
然后其他想要了解的类可以订阅,然后在它发生时接收相关详细信息。
这适用于多个消息的原因是因为通用类在 C# 中的工作方式。我的意思是,在幕后使用的每个不同泛型类型都会有一个委托(delegate)副本。
实际上,我在玩游戏时偶然发现了这一点,我很兴奋,因为它确实简化了我的代码,并且在这一点上看起来几乎像一种设计模式。
我在这里发帖询问使用这种方法的潜在缺点。封面下的通用委托(delegate)数量是否有限制?像这样的规模会有多好?
此外,有没有什么方法可以进行某种泛型类型推断,从而使语句不必这么长?
MessageHandler<MessagePlayerDamaged>.Publish(new MessagePlayerDamaged(this, this));
最佳答案
我实际上使用了非常相似的模式并取得了很大的成功。我采取的进一步措施是将实际的消息处理程序封装在 MessageHandlerRegistry
中,以允许更清晰的语法。这是您修改的示例:
Message.cs
public class Message
{
}
MessageHandler.cs
public class MessageHandler<T> where T : Message
{
private Action<T> messageHandlers;
public void Publish(T message)
{
messageHandlers(message);
}
public void Subscribe(Action<T> messageHandler)
{
messageHandlers = (Action<T>) Delegate.Combine(messageHandlers, messageHandler);
}
}
MessageHandlerRegistry.cs
public static class MessageHandlerRegistry
{
private static readonly IDictionary<Type, object> _handlers = new Dictionary<Type, object>();
public static void Publish<T>(T m) where T : Message
{
if (_handlers.ContainsKey(typeof (T)))
{
((MessageHandler<T>) _handlers[typeof (T)]).Publish(m);
}
}
public static void Subscribe<T>(Action<T> messageHandler) where T : Message
{
if (!_handlers.ContainsKey(typeof (T)))
{
_handlers[typeof (T)] = new MessageHandler<T>();
}
((MessageHandler<T>) _handlers[typeof (T)]).Subscribe(messageHandler);
}
}
Program.cs
class Program
{
static void Main(string[] args)
{
MessageHandlerRegistry.Subscribe((Message m) => Console.WriteLine("Message received."));
MessageHandlerRegistry.Publish(new Message());
}
}
我看到的唯一缺点是过度松散耦合,在某些情况下使用传统的基于事件的方法更有意义,有时只发布一条消息更容易。
关于c# - 尝试设计一个小型消息处理程序类来模拟 C# 事件。这种方法有什么缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13558422/