Странно, но корректно

Один из коллег недавно задал мне вопрос: «Может ли к свойству или методу применяться оба ключевых слова abstract и override . Я мгновенно ответил ему: «конечно, нет!», однако, как выяснилось, в коде проекта Roslyn есть свойства, с обоими ключевыми словами abstract и override. (Именно из-за этого и был задан этот вопрос.)

Я подумал над этим вопросом еще и пересмотрел свою точку зрения. Этот шаблон довольно редкий, но он совершенно корректный и даже разумный. У нас этот случай появился в коде огромной и очень сложной иерархии типов, используемой для представления множества различных концепций в компиляторе. Предположим, базовый класс называется “Thingy”:

 abstract class Thingy
{
  public virtual string Name { get { return ""; } }
}

У этого класса будет множество наследников, большинство из которых в качестве имени будут возвращать пустую строку, null или что-то еще. Важно не то, что они будут возвращать, а то, что у нас есть разумное имя по умолчанию, которое подходит большинству типов в нашей громадной иерархии.

Однако у нас есть другой абстрактный класс, наследник класса Thingy, скажем FrobThingy, который всегда должен возвращать не пустую строку в свойстве Name. Для предотвращения наследниками класса FrobThingy случайного использования реализации по умолчанию, доступной в базовом классе, мы объявляем следующее:

 abstract class FrobThingy : Thingy
{
  public abstract override string Name { get; }
}

Теперь, при создании наследника BigFrobThingy, вы знаете, что для компиляции вашего класса вам необходимо предоставить реализацию свойства Name.

Оригинал статьи