简体   繁体   中英

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?

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

Yes, trigger is of type ISubscriber which only has one HandleMessage method defined in its interface:

void HandleMessage(IMessage message)

There is no other method to match from the interface definition, so that only visible method is called. There is no overload resolution taking place here.

If you change ISubscriber trigger to TriggerSubscriber trigger (now there are two methods visible!) you will see you get the expected method called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM