gpt4 book ai didi

c# - 尝试设计一个小型消息处理程序类来模拟 C# 事件。这种方法有什么缺点?

转载 作者:行者123 更新时间:2023-11-30 16:21:04 24 4
gpt4 key购买 nike

这是我的代码:

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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com