Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different behaviour of method overloading in C#

I was going through C# Brainteasers (http://www.yoda.arachsys.com/csharp/teasers.html) and came across one question: what should be the output of this code?

class Base
{
    public virtual void Foo(int x)
    {
        Console.WriteLine ("Base.Foo(int)");
    }
}

class Derived : Base
{
    public override void Foo(int x)
    {
        Console.WriteLine ("Derived.Foo(int)");
    }

    public void Foo(object o)
    {
        Console.WriteLine ("Derived.Foo(object)");
    }
}

class Test
{
    static void Main()
    {
        Derived d = new Derived();
        int i = 10;
        d.Foo(i);  // it prints ("Derived.Foo(object)"
    }
} 

But if I change the code to

class Derived 
{
    public void Foo(int x)
    {
        Console.WriteLine("Derived.Foo(int)");
    }

    public void Foo(object o)
    {
        Console.WriteLine("Derived.Foo(object)");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Derived d = new Derived();
        int i = 10;
        d.Foo(i); // prints  Derived.Foo(int)");

        Console.ReadKey();
    }
}

I want to why the output is getting changed when we are inheriting vs not inheriting; why is method overloading behaving differently in these two cases?

like image 808
Wondering Avatar asked May 12 '10 18:05

Wondering


People also ask

How many types of overloading are there?

There are mainly two types of overloading, i.e. function overloading and operator overloading.

What is method overloading in C language?

Function overloading is a feature of a programming language that allows one to have many functions with same name but with different signatures. This feature is present in most of the Object Oriented Languages such as C++ and Java.

What is overloading explain different types of overloading with examples?

Function Overloading is defined as the process of having two or more function with the same name, but different in parameters is known as function overloading in C++. In function overloading, the function is redefined by using either different types of arguments or a different number of arguments.


2 Answers

As I specified in the answers page:

Derived.Foo(object) is printed - when choosing an overload, if there are any compatible methods declared in a derived class, all signatures declared in the base class are ignored - even if they're overridden in the same derived class!

In other words, the compiler looks at methods which are freshly-declared in the most derived class (based on the compile-time type of the expression) and sees if any are applicable. If they are, it uses the "best" one available. If none is applicable, it tries the base class, and so on. An overridden method doesn't count as being declared in the derived class.

See sections 7.4.3 and 7.5.5.1 of the C# 3 spec for more details.

Now as for exactly why it's specified like that - I don't know. It makes sense to me that methods declared in the derived class take precedence over those declared in the base class, as otherwise you run into the "brittle base class" problem - adding a method in the base class could change the meaning of code using the derived class. However, if the derived class is overriding the method declared in the base class, it's clearly aware of it, so that element of brittleness doesn't apply.

like image 177
Jon Skeet Avatar answered Sep 20 '22 16:09

Jon Skeet


It revolves around scope. In the first program, void Foo(int i) belongs to class Base. class Derived merely redefines its behavior.

Foo(int i) is ignored because it's being "borrowed" and redefined via inheritance from class Base. if Foo(object o) did not exist, then Foo(int i) would be used.

In the second program, void Foo(int i) is called because it properly belongs to class Derived (i.e. it's not being borrowed and overriden through inheritance) and has the best signature fit.

like image 24
sechastain Avatar answered Sep 19 '22 16:09

sechastain