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?
As I specified in the answers page:
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.