9
class Base
{
    public virtual void MethodA(int x)
    {
        Console.WriteLine ("In Base Class");
    }
}

class Derived : Base
{
    public override void MethodA(int x)
    {
        Console.WriteLine ("In derived INT)");
    }

    public void MethodA(object o)
    {
        Console.WriteLine ("In derived OBJECT");
    }
}

class Test
{
    static void Main()
    {
        Derived d = new Derived();
        int k = 20;
        d.MethodA(k);
    }
}

The output I got for this is "In derived OBJECT". What is the reason for this strange behaviour? After some research, I found out the reason is the signatures declared in the base class are ignored. Why are they ignored?

adelphus
  • 10,116
  • 5
  • 36
  • 46
Sandeep
  • 7,156
  • 12
  • 45
  • 57
  • 1
    +1 to the question, I agree this is counter-intuitive behavior. – Kirk Woll Sep 05 '10 at 22:30
  • I agree that the behaviour is strange. I'd like to know: are you asking this because you actually want to do this or because you were curious? I can't see a reason to actually implement something like this, but I'd definitely like to know why it happens. – Samir Talwar Sep 05 '10 at 22:41
  • possible duplicate of [How method hiding works in C#? (Part Two)](http://stackoverflow.com/questions/710459/how-method-hiding-works-in-c-part-two) – Ahmad Mageed Sep 05 '10 at 22:57
  • The code in the question is almost identical to that in this answer: http://stackoverflow.com/questions/710459/how-method-hiding-works-in-c-part-two/710493#710493 , so there you go. – H H Sep 05 '10 at 23:05

2 Answers2

7

This is by design and for a good reason. This design helps prevent the Brittle Base Class problem. C# was designed to make it easier and safer to write "versioned" components, and this rule is a big part of that.

This is a very frequently asked question. This is one of the most common "false bug reports" that we get; that is, someone believes they have found a bug in the compiler when in fact they have found a feature.

For a description of the feature and why it is designed the way it is, see my article on the subject:

http://blogs.msdn.com/b/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx

For more articles on the subject of how various languages deal with the Brittle Base Class problem see my archive of articles on the subject:

http://blogs.msdn.com/b/ericlippert/archive/tags/brittle+base+classes/

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 1
    Becuase the MSDN blog site seems to have vanished... [Wayback machine link for blog post](https://web.archive.org/web/20150719022959/http://blogs.msdn.com/b/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx), and for [the taglist](https://web.archive.org/web/20150905090158/http://blogs.msdn.com/b/ericlippert/archive/tags/brittle+base+classes/) – TZHX Aug 08 '23 at 15:00
2

The compiler in VC# 2008 checks the available non-virtual functions before virtual ones, when deciding what to call. Since your Derived class has a non-virtual MethodA(object) that can be called, the compiler calls it.

If you add a virtual MethodA(object) to Base, then Derived.MethodA(int) will get called, because then both MethodA(object) and MethodA(int) are virtuals.

I'm not familiar enough with the C# language spec to know whether this is specified behavior, or a bug in the compiler.

mjfgates
  • 3,351
  • 1
  • 18
  • 15
  • It is indeed in the ECMA spec, non-virtual will be invoked first. Also note that the method that gets called is determined by the compiler for non-virtual methods, and by the runtime type for virtual methods. – Sander Rijken Sep 05 '10 at 22:56
  • I checked this, but beware that Derived.MethodA(int) will only get called when you add the keyword 'override' to Derived.MethodA(object) (that was meant of course). Without it the optional keyword 'new' is assumed and Derived.MethodA(object) will still get called. – Gerard Oct 19 '10 at 10:40