方法重载C#

Mar*_*sen 4 c# methods overloading

我是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?    
    }
}
Run Code Online (Sandbox Code Playgroud)

尝试处理以下消息:

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

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

public interface IMessage
{

}
Run Code Online (Sandbox Code Playgroud)

我预计会调用以下内容:

public void HandleMessage(TriggerMessage message)
Run Code Online (Sandbox Code Playgroud)

代替

public void HandleMessage(IMessage message)
Run Code Online (Sandbox Code Playgroud)

ISubscriber trigger = new TriggerSUbscriber();
trigger.HandleMessage(
    new TriggerMessage()
);
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?

Jcl*_*Jcl 6

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

void HandleMessage(IMessage message);
Run Code Online (Sandbox Code Playgroud)

所以编译器调用该方法.

事实上,如果你这样做:

class TriggerSubscriber : ISubscriber
{
  public void HandleMessage(IMessage message)
  {
  }
  public void HandleMessage(int something)
  {
  }
}
Run Code Online (Sandbox Code Playgroud)

然后尝试这样做:

ISubscriber trigger = new TriggerSubscriber();
trigger.HandleMessage(4);
Run Code Online (Sandbox Code Playgroud)

编译器会抱怨没有这样的方法ISubscriber来获取int参数.

有三种选择:

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

    ((TriggerSubscriber)trigger).HandleMessage(new TriggerMessage());
    
    Run Code Online (Sandbox Code Playgroud)
  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)
        {
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

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