Принудительный вызов виртуального метода базового класса внутри базового класса

2

Не поймите меня неправильно: я не хочу заставлять переопределяющий метод вызывать базовый класс, как уже просили 1000... раз раньше :)

Я задавался вопросом, есть ли способ принудительно вызвать реализацию метода базового класса внутри базового класса.

Пример:

using System;

public class Program
{
    public static void Main()
    {
        var c = new SubClass();
        c.CallInfo();
    }

    internal class BaseClass {
        protected virtual void Info(){
            Console.WriteLine("BaseClass");
        }

        internal virtual void CallInfo() {
            this.Info();
        }
    }

    internal class SubClass : BaseClass {
        protected override void Info() {
            Console.WriteLine("SubClass");
        }

        internal override void CallInfo() {
            base.CallInfo();
        }
    }
}

Выход, очевидно, будет SubClass. Есть ли способ заставить CallInfo метод BaseClass назвать свои собственные Info методы, так что выход будет BaseClass?

  • 0
    Вы можете создать конструктор для базового класса для вызова Info () самого себя во время его создания. Тем не менее, вы можете уточнить, что вы действительно пытаетесь достичь? Ожидаемый результат. Хотите увидеть ОБА содержимое WriteLine () подкласса и базового класса? Важно или нет, что сначала нужно сделать BaseClass, а затем Subclass?
  • 0
    Нет, как в комментарии к полужирному шрифту clearyfies: я не хочу форсировать вызов базового метода из подкласса. Просто форсировать вызов метода виртуальной базы из других базовых методов.
Теги:
oop
inheritance

2 ответа

4
Лучший ответ

Помечая ваш метод Info() как virtual вы специально запрашиваете такой тип наследования.

Если вы хотите убедиться, что вызов метода в вашем базовом классе не переопределен, вам нужно использовать не виртуальный метод, например

internal class BaseClass {
    protected virtual void Info(){
        this.FinalInfo();
    }

    protected void FinalInfo() {
        Console.WriteLine("BaseClass");
    }

    internal virtual void CallInfo() {
        this.FinalInfo();
    }
}
  • 0
    Спасибо за разъяснение виртуального ключевого слова. Этот «обходной путь» для меня очевиден, но мне было интересно, нет ли другого способа добиться того, чего я хочу.
  • 0
    @ infotoni91, что такого плохого в этом подходе, что вы ищете «другой путь»? Что заставляет вас чувствовать себя неловко / нерешительно в отношении подхода, показанного в ответе здесь?
Показать ещё 3 комментария
1

Нет, ты не можешь этого сделать. Назначение виртуальных методов состоит в том, что производные классы могут переопределять реализацию и что реализация используется даже при вызове ее из базовых классов.

Если это вызывает проблемы, то метод, который вы хотите запустить, не должен быть виртуальным.

Это сработает, хотя и не будет принудительно реализовывать реализацию подклассом вроде виртуального, оно позволит вам переопределить его.

public class Program
{
    public static void Main()
    {
        var c = new SubClass();
        c.CallInfo();
    }

    internal class BaseClass
    {
        protected void Info()
        {
            Console.WriteLine("BaseClass");
        }

        internal virtual void CallInfo()
        {
            this.Info();
        }
    }

    internal class SubClass : BaseClass
    {  
        protected new void Info()
        {
            Console.WriteLine("SubClass");
        }

        internal override void CallInfo()
        {
            base.CallInfo();
        }
    }
}
  • 0
    Сокрытие членов не эквивалентно переопределению (виртуального) метода. Таким образом, ваш ответ не соответствует контексту вопроса.
  • 0
    @elgonzo То, что он хочет сделать, невозможно, поэтому это было бы альтернативой, если ему действительно нужно использовать эту структуру.
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню