Давайте сначала убедимся, что я правильно понимаю ваш вопрос. У вас есть классы, определенные как выше. Вы создаете экземпляр A
и вызываете метод example
, который A
наследует от базового класса. Вы хотите знать, возможно ли для вызова this.AsAString()
в методе Letter.Example
вызвать базовую реализацию AsAString
, а не производную реализацию.
Во-первых, давайте разберемся, почему при example
, указанном выше, вызов Letter.example
через экземпляр A
(например, new A().example
) вызовет A.AsAString
. Из спецификации (§7.4.4):
Определена реализация члена функции для вызова:
Если тип времени компиляции E является интерфейсом, то вызываемый элемент функции является реализацией M, предоставленной типом времени выполнения экземпляра, на который ссылается E. Этот член функции определяется путем применения правил отображения интерфейса. (§13.4.4), чтобы определить реализацию M, обеспеченную типом времени выполнения экземпляра, на который ссылается E.
В противном случае, , если M является членом виртуальной функции, вызываемый элемент функции является реализацией M, обеспечиваемого типом времени выполнения экземпляра, на который ссылается E. Этот член функции определяется путем применения правил для определение наиболее производной реализации (§10.6.3) M относительно типа времени выполнения экземпляра, на который ссылается E.
В противном случае M - это не виртуальный член функции, а вызываемый элемент функции - это сам M.
Итак, теперь давайте рассмотрим вашу ситуацию. У вас есть экземпляр a
класса A
, производный от Letter
. Вы вызвали метод с именем example
через синтаксис a.example()
. Это вызовет Letter.example
, который имеет определение:
public void example() {
this.AsAString();
}
Это вызовет Letter.AsAString
. Но Letter.AsAString
объявляется virtual
, и, следовательно, по приведенному выше полужирному правилу вызывается метод A.AsAString
, поскольку this
имеет тип A
, A
происходит от Letter
, и A
обеспечивает override
из Letter.AsAString
.
Теперь, если вы измените определение A.AsAString
, чтобы оно скрывало базовую реализацию с помощью модификатора new
public new void AsAString() {
Console.WriteLine("A");
}
затем a.example
приведет к использованию базовой реализации, и вы увидите вывод ???
по своему желанию. Это связано с тем, что по вышеприведенному правилу наиболее производная реализация Letter.AsAString
(то есть наиболее производный тип в иерархии A
, который предоставляет определение virtual
метода AsAString
) является базовой реализацией. Модификатор new
позволяет A
иметь метод с именем AsAString
с той же сигнатурой, что и Letter.AsAString
, но это не метод virtual
.
Пожалуйста, дайте мне знать, если я неверно истолковываю ваш вопрос, или если что-то из вышеперечисленного требует разъяснения.