【问题标题】:Method overloading C#方法重载 C#
【发布时间】:2016-07-07 20:01:46
【问题描述】:

我是 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()
);

我错过了什么吗?

【问题讨论】:

    标签: c# methods overloading


    【解决方案1】:

    您的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,而不是可能有歧义),但你选择

    【讨论】:

    • 感谢您的回答,描述得很清楚。没有我希望的那么优雅,但这会做
    【解决方案2】:

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

    void HandleMessage(IMessage message)
    

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多