方法重载 C#

Method overloading C#

我是 C# 的新手,正在尝试弄清楚如何轻松实现以下内容:

我有一个订阅者:

public interface ISubscriber
{
    void HandleMessage(IMessage message);
}

class TriggerSubscriber : ISubscriber
{
    public void HandleMessage(IMessage message)
    {
         //This will be called by default   
    }
    public void HandleMessage(TriggerMessage message)
    {
         //This won't work, why?    
    }
}

正在尝试处理以下消息:

public class TriggerMessage : IMessage
{
    string identifier { get; set; }

    public TriggerMessage(string triggerIdentifier)
    {
        identifier = triggerIdentifier;
    }
}

public interface IMessage
{

}

我预计会调用以下内容:

public void HandleMessage(TriggerMessage message)

而不是

public void HandleMessage(IMessage message)

ISubscriber trigger = new TriggerSUbscriber();
trigger.HandleMessage(
    new TriggerMessage()
);

我是不是遗漏了什么?

是的,triggerISubscriber 类型,它的接口中只定义了一个 HandleMessage 方法:

void HandleMessage(IMessage message)

接口定义中没有其他方法可以匹配,所以只调用了可见的方法。这里没有发生重载决议。

如果您将 ISubscriber trigger 更改为 TriggerSubscriber trigger(现在有两个方法可见!)您将看到您调用了预期的方法。

您的 trigger 变量被定义为 ISubscriber 类型(无论实际对象类型是什么)。 ISubscriber 只有一个方法签名:

void HandleMessage(IMessage message);

因此编译器调用该方法。

事实上,如果你这样做:

class TriggerSubscriber : ISubscriber
{
  public void HandleMessage(IMessage message)
  {
  }
  public void HandleMessage(int something)
  {
  }
}

然后尝试这样做:

ISubscriber trigger = new TriggerSubscriber();
trigger.HandleMessage(4);

编译器会抱怨 ISubscriber 中没有这样的方法,它接受 int 参数。

共有三个选项:

  1. 将特定的TriggerMessage方法添加到接口
  2. 将您的 trigger 变量声明为 TriggerSubscriber,而不是 ISubscriber,或者在调用 HandleMessage 时将其转换为 TriggerSubscriber :

    ((TriggerSubscriber)trigger).HandleMessage(new TriggerMessage());
    
  3. 执行中解决:

    class TriggerSubscriber : ISubscriber
    {
        public void HandleMessage(IMessage message)
        {
          var triggerMessage = message as TriggerMessage;
          if(triggerMessage != null)
          {
             // Casting is not necessary, but I'd still put it
             // here just to make it clear
             HandleMessage((TriggerMessage)triggerMessage);
             return;
          }
          // other code
        }
        public void HandleMessage(TriggerMessage message)
        {
        }
    }
    

我肯定会使用#3(我会调用接收 TriggerMessage 类似 HandleTriggerMessage 的方法,而不是可能出现歧义),但你选择