【问题标题】:Interface/Inheritance/Delegate design issue接口/继承/委托设计问题
【发布时间】:2010-08-12 16:51:34
【问题描述】:

我有一组消息,它们都派生自 Message,并实现接口 IMessage:

class Message : IMessage
{
   public string example1;
}

class LogOnMessage : Message
{
   public string password;
}

class LogOffMessage : Message
{
   public string anotherExample;
}

我有一个消息传递系统,其中代理能够检测传入的消息,并根据消息的类型运行表单的委托

void MyDelegate(IMessage msg)

这是通过像这样调用处理程序注册函数来完成的:

RegisterHandler(typeof(LogoffMessage),handler)

对此的实现只是一个类型的字典,每个条目都是一个处理程序列表:Dictionary >

现在,这一切都很好,但处理程序当然看起来像这样:

void MyHandler(IMessage msg)
{
   LogOffMessage lMsg = (LogOffMessage)msg;
   string athrEx = lMsg.anotherExample;

//Proceed with handling the logoff
}

现在,这有几个问题。一是您可能会尝试将 Msg 转换为错误的类型。

另一个是,在任何处理程序的前几行中都必须解开所有内容,而不是拥有像这样的处理程序,我想拥有这样的处理程序有点不雅:

void MyDelegate(LogOffMessage msg)

你会提出什么建议?

我在想也许不是类型字典,而是可以使用一些其他结构来保存不同的委托类型,使用泛型。因此,每种类型都会有一个 MyDelegate 列表。但是目前还不清楚如何制作集合的集合,其中每个内部集合类型不同。

【问题讨论】:

    标签: c# .net inheritance interface


    【解决方案1】:

    使您的委托具有通用性:

    delegate void MessageHandler<T>(T message) where T : IMessage
    

    并使您的 RegisterHandler 方法通用:

    void RegisterHandler<T>(MessageHandler<T> handler)
    

    然后调用它:

    RegisterHandler(handler); // Let type inference handle it
    RegisterHandler<LogOffMessage>(handler); // State type argument explicitly
    

    然后,当您按类型获取委托时,您可以将其转换为正确的处理程序类型 - 即使从编译器的角度来看它是“不安全的”,您知道您只会拥有向字典中添加了正确类型的处理程序:

    // When you populate this, create the appropriate type of
    // `List<MessageHandler<T>>` based on the key
    private Dictionary<Type, object> handlerMap;
    
    void CallHandlers<T>(T message) where T : IMessage
    {
        object value;
        if (handlerMap.TryGetValue(typeof(T), out value))
        {
            List<MessageHandler<T>> handlers = (List<MessageHandler<T>>) value;
            foreach (MessageHandler<T> handler : handlers)
            {
                handler(message);
            }
        }
    }
    

    请注意,使用 List&lt;MessageHandler&lt;T&gt;&gt; 的另一种替代方法是组合委托并最终在映射中为每种类型创建一个多播委托。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-22
      • 1970-01-01
      • 2015-11-12
      • 1970-01-01
      • 1970-01-01
      • 2012-10-11
      相关资源
      最近更新 更多