views:

137

answers:

3

I have the following code sample :

public class Base
{
   public virtual void MyMethod(int param)
    {
        Console.WriteLine("Base:MyMethod - Int {0}", param);
    }
}

public class Derived1 : Base
{
    public override void MyMethod(int param)
    {
        Console.WriteLine("Derived1:MyMethod - Int {0}", param);
    }

    public void MyMethod(double param)
    {
        Console.WriteLine("Derived1:MyMethod - Double {0}", param);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Base objB = new Base();
        objB.MyMethod(5);

        Base objBD = new Derived1();
        objBD.MyMethod(5);

        Derived1 objD = new Derived1();
        objD.MyMethod(5);

        Console.ReadLine();
    }
}

The output of the above code is as follows:

Base:MyMethod - Int 5

Derived1:MyMethod - Int 5

Derived1:MyMethod - Double 5

For the third invocation of 'MyMethod' using 'objD' why is the 'DOUBLE' overload being used when I am actually passing it an INT.

The second invocation using 'objBD' seems to behave correctly. Please suggest.

A: 

I'd guess that when calling MyMethod(5), 5 could be a double or an int as well and double has higher priority. Have you tried calling MyMethod((int)5)?

schnaader
+8  A: 

Oddly, I was discussing this with Jon the other evening! There is a precedence issue - the overridden method is defined in the base-class, so for "best method" purposes, the overload (even with an implicit cast) is preferable, since it is defined in the most-specific type (the subclass).

If you re-declared the method (new), then it would get precedence, but you can't override and new a method with the same name and signature in the same type - you'd have to add an extra level of inheritance to achieve this.

The exact logic for this is detailed in 14.5.5 and 14.4.2 of ECMA 334 v4.

Basically, to make the base method callable, you'll either have to cast to the base-type, or add a shim method:

public void MyMethod2(int param) {base.MyMethod(param);}
Marc Gravell
Is there an updated ECMA specification that includes things like LINQ, automatic properties, etc.? The one you're referring to, v4, doesn't.
Lasse V. Karlsen
Or, barring that, what document does include all that? Should I just buy the annotated C# specification book I saw somewhere? Is there an electronic version available of that that you know of? (I know, hijacking your answer... :))
Lasse V. Karlsen
The Micosoft spec does - I'll dig out a link...
Marc Gravell
http://download.microsoft.com/download/3/8/8/388e7205-bc10-4226-b2a8-75351c669b09/csharp%20language%20specification.doc
Marc Gravell
I just went and purchased an adobe version of the annotated C# spec, 3rd edition, but I'll go and download that word document as well. Thanks!
Lasse V. Karlsen
A: 

I did the following change as suggested :

        Derived1 objD = new Derived1();
        objD.MyMethod((int)5);

The output doesnt change

Base:MyMethod - Int 5

Derived1:MyMethod - Int 5

Derived1:MyMethod - Double 5

Codex
So it seems Marc is right, +1 for him
schnaader
5 is already an int, the explicit cast doesn't help, it can still be implicitly cast to a double. BTW, please respond to specific answers using 'add comment' not by adding another answer.
AnthonyWJones