I have some - probably really stupid - question on overload resolution.
Suppose there is a constrained generic method Greet
accepting parameter person
of type T
which must derive from Person
. This Greet
method then calls some non-generic method in another class passing that person
as parameter. That non-generic method has several overloads - for the base class and for a derived class. Why is the overload for the base class always called?
Example:
public static class Test
{
public static void Greet()
{
new SomeClass().Greet(new Person()); // Hi, I am a Person
new SomeClass().Greet(new Manager()); // Hi, I am a Person -- Why?
}
}
public class SomeClass
{
public void Greet<T>(T person) where T : Person
{
new Greeter().SayHi(person);
}
}
public class Person { /* some props and methods */ }
public class Manager : Person { /* some props and methods */ }
public class Greeter
{
public SayHi(Person person) { Console.WriteLine("Hi, I am a person"); }
public SayHi(Manager person) { Console.WriteLine("Hi, I am a manager"); }
}
However, only the SayHi accepting a Person is always called. Why?
The compiler has to perform overload resolution for the call of
new Greeter().SayHi(person);
At that point, the type of person
is just T
, and all it knows is that T
is implicitly convertible to Person
. Therefore, the only applicable method in Greeter
is SayHi(Person)
.
It's important to understand that this happens at compile-time, once - it doesn't occur at execution time separately for each type argument that's used for T
.
See more on this question at Stackoverflow