C#中的方法重载

4
我是一名新手,正在学习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()
);

我有什么遗漏吗?
2个回答

6

您的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. Add the specific TriggerMessage method to the interface
  2. Declare your trigger variable as TriggerSubscriber, instead of as ISubscriber, or cast it to TriggerSubscriber when calling HandleMessage:

    ((TriggerSubscriber)trigger).HandleMessage(new TriggerMessage());
    
  3. Solve it in the implementation:

    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)
        {
        }
    }
    
我肯定会使用第三种方法(并且我会将接收TriggerMessage的方法称为HandleTriggerMessage,以避免可能存在的歧义)。但这个选择由您决定。

非常感谢您的回答,解释得非常清楚。虽然不如我所期望的那样优美,但这已经足够了。 - Marco Janssen

2

是的,trigger 的类型是 ISubscriber,它只在其接口中定义了一个 HandleMessage 方法:

void HandleMessage(IMessage message)

在接口定义中没有其他方法可以匹配,因此只调用可见方法。这里不进行重载解析。

如果将ISubscriber触发器更改为TriggerSubscriber触发器(现在有两种方法可见!),则会看到您调用了预期的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接