【问题标题】:How do I call different methods for different class-types in a generic message-receiver?如何在通用消息接收器中为不同的类类型调用不同的方法?
【发布时间】:2012-04-08 12:47:18
【问题描述】:

假设我有一个名为 IMessage 的基类,以及许多派生消息类。

在我的程序中,我有一种方法可以接收所有消息:

void ReceiveMessage(IMessage message)
{
}

我想为每种类型的消息调用一个特定的方法。 如果我能做到,那就太好了:

void ReceiveMessage(IMessage message)
{
    HandleMessage(message);
}

void HandleMessage(DummyMessage message)
{
    Blah;
}

void HandleMessage(SillyMessage message)
{
    Yuk;
}

..但显然“我们不会那样出去的”。

那么我将如何为特定消息实现特定的处理程序,从单个消息处理程序调用?

【问题讨论】:

  • IMessage 接口是否应该定义所有 IMessage 实现都实现的“通用”方法,从而允许您在 ReceiveMessage 方法中调用这些方法?
  • @TrevorPilley 这取决于。有时这是不合适的。例如,许多游戏引擎或 3D 场景图都会遇到场景中不同“演员”对每种场景类型(消息)的处理方式非常不同的情况。
  • 我希望处理程序在另一个类中被调用,而不是在消息本身中......(例如,一个服务器类应该包含不同消息的所有处理程序)

标签: c# class methods handler derived


【解决方案1】:

尝试使用工厂方法。查找工厂设计模式。

【讨论】:

    【解决方案2】:

    你的 IMessage 接口应该定义一个 HandleMessage() 函数,每个类型都实现:

    public interface IMessage
    {
        void HandleMessage();
    }
    
    public class DummyMessage : IMessage
    {
         public void HandleMessage()
         {
             Blah;
         }
    }
    
    public class SillyMessage : IMessage
    {
         public void HandleMessage()
         {
             Yak;
         }
    }
    

    那么你可以这样称呼它:

    void ReceiveMessage(IMessage message)
    {
        message.HandleMessage();
    }
    

    【讨论】:

    • 如果多个接收者需要以不同的方式处理单个消息类型,这将不起作用。在这种情况下,访问者模式是处理此类场景的经典方式。
    【解决方案3】:

    处理这种情况的经典方法是通过Visitor pattern

    话虽如此,您实际上可以通过dynamic 在 C# 中更轻松地处理这个问题,如下所示:

    void ReceiveMessage(IMessage message)
    {
        dynamic specificMessage = message;
        this.HandleMessage(specificMessage):
    }
    

    动态绑定引擎将在运行时为您的特定消息类型找到“最佳”匹配,并将调用路由到适当的方法。

    【讨论】:

    • 谢谢,幸运的是我的目标是 .net 4.0,所以动态节省了一天! \o/
    【解决方案4】:

    可以按照您的建议去做,虽然它不是很干燥,我认为这里的其他建议更合适。尽管如此,为了完整起见,这里有一种接近您最初寻找的方法:

    void ReceiveMessage( IMessage message ) {
      if( message as DummyMessage != null ) HandleMessage( message as DummyMessage );
      else if( message as SillyMessage != null ) HandleMessage( message as SillyMessage );
      // etc
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-20
      • 1970-01-01
      • 1970-01-01
      • 2018-08-28
      • 2016-12-23
      • 2015-01-10
      相关资源
      最近更新 更多