Значения по умолчанию в .Net являются синтаксическим сахаром, основанным на компиляторе. На сайте вызовов компилятор добавляет значения по умолчанию для вас. Он не может знать тип времени выполнения вашего объекта во время компиляции, поэтому он должен вставить значение, определенное в интерфейсе.
Следовательно, они не могут быть «переопределены» в реализациях, потому что нечего переопределять.
Эрик Липперт написал очень интересную серию постов в блоге на тему необязательных аргументов, первый из которых можно найти здесь .
Обновление
Из ваших комментариев вы предлагаете либо некоторую форму «виртуального» параметра (в котором объявляется тип среды выполнения), о котором CLR должен был бы «знать». Я предполагаю, что эта реализация была исключена, потому что затраты (разработка, документирование, реализация, тестирование и т. Д.) Были слишком высоки по сравнению с преимуществами, которые она дала (хотя это только предположение!).
В качестве альтернативы есть опция метода делегирования по умолчанию, например:
void M(bool y = false) { ... whatever ... }
Получает переписанный компилятором как:
void M() { M(false); }
void M(bool y) { ... whatever ... }
Но переход по этому маршруту приводит к потенциально неприемлемому уровню перегрузок, если учитывать несколько необязательных аргументов и именованных аргументов.