Метод перегрузки резолюции и Джон Скит Мозг тизеры
Jon Brain Teasers
Здесь будут Спойлеры...
Я смотрю answer на # 1, и я должен признать, что я никогда не знал, что это было в случае разрешения перегрузки. Но почему этот случай. В моем маленьком уме Derived.Foo(int)
кажется логическим путем идти вниз.
Какова логика этого дизайнерского решения?
БОНУСНОЕ ВРЕМЯ!
Является ли это поведение результатом спецификации С#, реализации CLR или компилятора?
Ответы
Ответ 1
Такое поведение преднамеренное и тщательно продуманное. Причина в том, что этот выбор смягчает влияние одной из форм ошибки хрупкого базового класса.
Прочтите мою статью по этому вопросу для более подробной информации.
http://blogs.msdn.com/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx
Ответ 2
Вот возможное объяснение:
Когда компилятор связывает вызовы метода, первое место он ищет в классе, который является самым низким в цепочке наследования (в этом случае класс Derived
). Проверяются и сопоставляются методы экземпляра. Переопределенный метод Foo не является методом экземпляра Derived
, это метод экземпляра класса Base
.
Причиной может быть производительность, как предлагал Джек30lena, но также может быть так, как компилятор интерпретирует намерение кодера. Это безопасное предположение о том, что разработчик предполагает поведение кода в коде, расположенном в нижней части цепочки наследования.
Ответ 3
Это результат компилятора, мы рассмотрели код IL.
Ответ 4
Причина в том, что это неоднозначно. Компилятор просто должен решить для одного. И кто-то подумал, что менее косвенным будет лучше (производительность может быть причиной).
Если разработчик только что написал:
((Base)d).Foo (i);
ясно и дает ожидаемый результат.
Ответ 5
причина такова: производительность.
вызов виртуального метода занимает немного больше времени. вызов делегата по виртуальному методу занимает гораздо больше времени и т.д....
см:
Стоимость вызовов методов