С# Перегруженный вызов метода с наследованием

Интересно, в чем причина вызова метода, который печатает "double in производный". Я не нашел в этом никаких подсказок в спецификации С#.

public class A
{
    public virtual void Print(int x)
    {
        Console.WriteLine("int in base");
    }
}

public class B : A
{
    public override void Print(int x)
    {
        Console.WriteLine("int in derived");
    }
    public void Print(double x)
    {
        Console.WriteLine("double in derived");
    }
}



B bb = new B();
bb.Print(2);

Ответ 1

Прямо от спецификации С# (7.5.3 Разрешение перегрузки):

набор кандидатов для вызова метода не включает методы, отмеченные как переопределение (§7.4), и методы в базовом классе не являются кандидатами, если любой метод в производный класс применим (§7.6.5.1).

В вашем примере переопределенный Print(int x) не является кандидатом и Print(double x) применим, поэтому он выбирается без необходимости рассматривать методы в базовом классе.

Ответ 2

Компилятор рассматривает методы, которые только что объявлены в самом производном классе (на основе типа времени компиляции), и видит, применимы ли они. Если они есть, он использует "лучший" доступный.

См. ответ на этот вопрос:

Различное поведение перегрузки методов на С#