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, whereC
is the type in which the methodF
is declared, all methods declared in a base type ofC
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:
If you want it to do overloading based on argument type, put both versions of the method in the same type.