Почему C # не позволяет вызывать base.SomeAbstractMethod

Вот код для обсуждения

  abstract class ClassA
  {
    public abstract void StartProcess();
  }

  class ClassB : ClassA
  {
    public override void StartProcess()
    {      
      Console.WriteLine("ClassB: Render");
    }
  }

  class ClassC : ClassA
  {
    public override void StartProcess()
    {
      base.StartProcess();//This is where the compiler complains
      Console.WriteLine("ClassC: Render");
    }
  }

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

Исходя из фона Delphi, мы могли бы сделать это в Delphi и использовать его в дизайне нашего класса. Если вы допустили ошибку, вызвав абстрактный метод в базовом классе (во время выполнения), вы получите «Абстрактную ошибку».

Тогда я хотел бы, чтобы компилятор (Delphi) проверил меня раньше! Теперь я хочу, чтобы компилятор (C #) позволил мне это сделать! Насколько это странно?

Вопросы: Не мог ли компилятор / Jitter просто проигнорировать такой вызов и выдать предупреждение вместо ошибки? Видят / чувствуют ли другие эту боль?

Случай, в котором я нуждаюсь, следующий: ClassA является частью библиотеки (нет контроля над этим классом) ClassC генерируется (вроде того, как компилируется страница ASP.NET или компилируется Razor View.

Но пользователь библиотеки может определить ClassB, и тогда ClassC будет происходить от ClassB вместо ClassA (когда он создается Подобно тому, как страницы ASP.NET обычно происходят от System.Web.UI.Page, но если вы определили свою собственную «базовую» страницу, а другие страницы в вашем приложении теперь являются потомками вашей базовой страницы, то сгенерированный класс наследуется от вашей базовая страница (которая, в свою очередь, происходит от System.Web.UI.Page).

Я надеюсь, что эта часть понятна. Затем, глядя на представленный мной код, я не могу заставить экземпляры ClassC вызывать реализацию класса B, потому что генератор кода не знает, что нужно включать base.StartProcess ().

ИЗМЕНИТЬ Кажется, что некоторые люди не совсем поняли то, что я написал. Итак, допустим, вы писали часть генерации кода, которая генерирует ClassC, который происходит от ClassA. Что ж, поскольку метод является абстрактным (в ClassA), вы не можете сгенерировать строку кода, которая вызывает StartProcess () (потому что компилятор не позволит этого). В результате, если кто-то определит ClassB, генерация кода все равно не вызовет base.StartProcess (). Фактически это то, что происходит в представлениях ASP.NET MVC.

В идеале я бы хотел, чтобы компилятор игнорировал это. Он игнорирует многие вещи, например, вызов метода dispose для нулевой ссылки.

Я пытаюсь провести обсуждение, а не проповедовать ...

EDIT2 Предположим, у нас есть иерархия, как показано в приведенном выше коде, и она работает. Сейчас у нас есть возможность, что базовый класс ClassA может иметь реализацию (в будущем) для потомков StartProcess (), которые будут вызывать его. Единственный способ сделать это сегодня - определить метод virtual без тела. Но мне это кажется немного неприятным.

6
задан Jackie Kirby 4 March 2011 в 21:40
поделиться