Bolha
Bolha

Reputation: 253

C# overloading resolution with hierarchical parameters

In the example I was expecting to get Third as output since class Third has an exact signature match to the Print call, but the output is Second. Why that happens?

class First
{
    public virtual void Print(string x)
    {
        Console.WriteLine("First");
    }
}

class Second : First
{
    public void Print(object x)
    {
        Console.WriteLine("Second");
    }
}

class Third : Second
{
    public override void Print(string x)
    {
        Console.WriteLine("Third");
    }
}

class Program
{
    static void Main(string[] args)
    {
        string sss = "lalala";
        Third t = new Third();    
        t.Print(sss);

        Console.ReadLine();
    }
}

Upvotes: 4

Views: 344

Answers (2)

Gustavo Mori
Gustavo Mori

Reputation: 8386

Just to add to Ivan's answer, I was surprised that you didn't mention getting a warning.

But then I noticed that you have 3 very similar, but not identical methods. The Print method in class Second takes an object, not a string, which is what the other two classes specify. So, the compiler thinks that you're introducing an overload to the Print method declared in First, not an override nor hiding. And as mentioned in comments by other contributors, you see this behavior because the overload in the more derived class (Third) is more specific than the one in the base class (Second)

A look at the class diagram will help see this:

enter image description here

If you changed the signature in Second to take a string, your friendly compiler would have alerted you with:

Warning 1 'Second.Print(string)' hides inherited member 'First.Print(string)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword. Program.cs 40 21 C

and:

Error 2 'Third.Print(string)': cannot override inherited member 'Second.Print(string)' because it is not marked virtual, abstract, or override Program.cs 48 30 C

Take a look at this MSDN article for more info.

Upvotes: 1

Ivan Danilov
Ivan Danilov

Reputation: 14777

See here:

...the set of candidates for a method invocation does not include methods marked override (Section 7.3), and methods in a base class are not candidates if any method in a derived class is applicable (Section 7.5.5.1).

Thus, overriden method in the Third is not applicable and Second.Print(object) hides base class implementation and becomes single candidate.

Upvotes: 5

Related Questions