My understanding (in C#) of how non-virtual methods are resolved is that it is dependent upon the type of the variable (and not the type of instance).
Take a look at the code below.
class Program
{
static void Main(string[] args)
{
Sedan vehicle = new Sedan();
vehicle.Drive();
vehicle.Accelerate();
}
}
abstract class VehicleBase
{
public void Drive()
{
ShiftIntoGear();
Accelerate();
Steer();
}
protected abstract void ShiftIntoGear();
protected abstract void Steer();
public void Accelerate()
{
Console.WriteLine("VehicleBase.Accelerate");
}
}
class Sedan : VehicleBase
{
protected override void ShiftIntoGear()
{
Console.WriteLine("Sedan.ShiftIntoGear");
}
protected override void Steer()
{
Console.WriteLine("Sedan.Steer");
}
public new void Accelerate()
{
Console.WriteLine("Sedan.Accelerate");
}
}
The Console Windows shows the following:
Sedan.ShiftIntoGear
VehicleBase.Accelerate
Sedan.Steer
Sedan.Accelerate
This doesn't make sense to me and I believe would throw many folks for a loop. If you now declare variable vehicle to be of type VehicleBase you get
Sedan.ShiftIntoGear
VehicleBase.Accelerate
Sedan.Steer
VehicleBase.Accelerate
Which is what I'd expect in the previous case as well because the method Accelerate is non-virtual.
In the previous output, (with the variable vehicle typed as a Sedan, I'd expect the Sedan.Accelerate to be called instead of VehicleBase.Accelerate. As it stands now, depending on where you call it from (from within the class or from outside) the behavior is changing.
It seems to me that the overload resolution rule(s) for re-introduced methods is taking precedence but I have a hard time believing that this is correct/expected behavior.