Home > Software engineering >  Why does this function call resolve to the base class method, casting the int to a double?
Why does this function call resolve to the base class method, casting the int to a double?

Time:02-16

Why does this program print "abc from B" instead of "abc from A"? My intuition says that it should resolve the method to the more specific type parameter (which is how I've always used overloading).

    public class Program
    {
        public static void Main(string[] args)
        {
            int i = 5;
            B b = new B();
            b.Method1(i);
            Console.ReadLine();
        }
    }

    class A
    {
        public void Method1(int q)
        {
            Console.WriteLine("abc from A");
        }
    }

    class B : A
    {
        public void Method1(double p)
        {
            Console.WriteLine("abc from B");
        }
    }

CodePudding user response:

Overload resolution doesn't work across types.

This is due to one crucial step in determining the set of candidate methods for overload resolution, as stated in the language spec:

The set of candidate methods is reduced to contain only methods from the most derived types: For each method C.F in the set, where C is the type in which the method F is declared, all methods declared in a base type of C are removed from the set.

Basically, the A.Method1 isn't even considered for overload resolution.

There are a few other steps to this, but the spec nicely summarises the process:

To locate the particular method invoked by a method invocation, start with the type indicated by the method invocation and proceed up the inheritance chain until at least one applicable, accessible, non-override method declaration is found. Then perform type inference and overload resolution on the set of applicable, accessible, non-override methods declared in that type and invoke the method thus selected.

Interestingly, your intuition that A.Method1 should be called because there is an identity conversion from int to int is how it works in Java :)

CodePudding user response:

Because you called it from a variable of the B type. If you cast b as an A, you'd get the first result. See it here:

https://dotnetfiddle.net/TAYfJX

If you want it to do overloading based on argument type, put both versions of the method in the same type.

  •  Tags:  
  • c#
  • Related