Ответ 1
Почему компилятор не выбирает более подходящий метод?
Поскольку он соответствует правилам спецификации языка, где любые методы-кандидаты, первоначально объявленные в базовом классе (если они переопределены в производном классе), игнорируются при поиске метода-кандидата, если только производный класс не имеют какие-либо применимые методы, после чего поиск перемещается до базового класса и т.д.
Это чтобы избежать проблемы с "хрупким базовым классом" , но я считаю, что трудно усвоить перед лицом переопределенного метода в производном классе.
Соответствующий бит спецификации С# 4 равен 7.4, который заканчивается следующим:
Для поиска членов в типах, отличных от параметров и интерфейсов типа, и поиска элементов в интерфейсах, которые строго однонаправленны (каждый интерфейс в цепочке наследования имеет ровно нулевой или один прямой базовый интерфейс), эффект правил поиска просто производные члены скрывают базовые элементы с тем же именем или подписью.
EDIT: О методах расширения...
И почему это не метод расширения?
Из раздела 7.6.5.2 спецификации:
В вызове метода (п. 7.5.5.1) одной из форм
expr . identifier ( ) expr . identifier ( args ) expr . identifier < typeargs > ( ) expr . identifier < typeargs > ( args )
если нормальная обработка вызова не находит применимых методов, делается попытка обработать конструкцию как вызов метода расширения
Таким образом, метод расширения используется в основном как последнее средство.