Странно, но корректно
Один из коллег недавно задал мне вопрос: «Может ли к свойству или методу применяться оба ключевых слова 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.