Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method overloading C#

I'm new to C# and trying to figure out how i can easily implement the following:

I have a subscriber:

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?    
    }
}

Trying to handle the following message:

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

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

public interface IMessage
{

}

I expected that the following would have been called:

public void HandleMessage(TriggerMessage message)

instead of

public void HandleMessage(IMessage message)

with

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

Am i missing something here?

like image 463
Marco Janssen Avatar asked Feb 08 '23 10:02

Marco Janssen


1 Answers

Your trigger variable is defined as it being of type ISubscriber (no matter what the actual object type is). ISubscriber only has one method signature:

void HandleMessage(IMessage message);

So the compiler calls that method.

In fact, if you did this:

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

And then try to do this:

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

The compiler will complain that there's no such method in ISubscriber which takes an int parameter.

There are three options:

  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)
        {
        }
    }
    

I'd definitely use #3 (and I'd call the method that receives a TriggerMessage something like HandleTriggerMessage, instead of having possible ambiguities), but you choose

like image 97
Jcl Avatar answered Feb 16 '23 04:02

Jcl