tw1ggyz
@tw1ggyz

Как в C# запретить подклассам переопределять метод суперкласса?

Хочу создавать объекты, которые модифицируют переданную им строку. При этом нужно, чтобы никто из них не забывал проверять, а не пустая ли строка и передана ли она вообще.
=> создаю базовый абстрактный класс, в котором два метода:
* Modify, который инкапсулирует эту проверку и вызывает MakeTransform, если проверка пройдена
* MakeTransform - метод, непосредственно выполняющий трансформацию. Его реализуют потомки
public abstract class Modifier
{
        public string Modify(string str)
        {
            if (str == null || str.Length == 0)
                throw new ArgumentNullException("Ошибка модификатора. Строка пустая.");

            return MakeTransform(str);
        }

        protected abstract string MakeTransform(string str);
}

Создаю потомка. Он будет выполнять модификацию, например, по регулярному выражению. Реализую MakeTransform, как и предполагалось. Теперь по задумке ему достаточно вызвать Modify, полученный от родителя, и все проверки и прочая рутина выполнится для него прозрачным образом так, что он и не узнает. Шаблонный метод получается.
Но тут я или другой пользователь класса посмотрел в окно, отвлекся, и написал еще и реализацию для Modify, которая перекрыла родительскую:
public class RegexModifier : Modifier
{
        private string _pattern;

        public RegexModifier(string pattern)
        {
            _pattern = pattern;
        }

        protected override string MakeTransform(string source)
        {
            return Regex.Match(source, _pattern).Value;
        }

        public string Modify(string source)
        {
            return source;
        }
}

В итоге очевидно ничего не работает, строка проскакивает без задуманной модификации
class Program
{
        static void Main(string[] args)
        {
            var rmod = new RegexModifier(@"[ \p{L}]*");
            Console.WriteLine(rmod.Modify("Hello World321"));  // Вместо ожидаемого Hello Wolrd получаем исходную строку
        }
}

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

Есть sealed для методов, но он тут не подходит. Как же сделать?
  • Вопрос задан
  • 601 просмотр
Решения вопроса 1
shai_hulud
@shai_hulud
Ну, во первых, это варнинг про то что один метод "закрывает" другой метод своим именем.

Идём в настройки проекта и ставим:
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>


По дефолту в каждом новом проекте оно должно быть true т.к. все варнинги С# (даже по документации) это ошибки разработчиков.

По проблеме: способов запретить перекрытие имён нет. Можно написать аналитику Roslyn на нахождение таких перекрытий, можно в рантайме чекнуть что в потомке нет такого же метода.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Griboks
@Griboks Куратор тега C#
чего бы не произошло, если бы у меня на этапе компиляции был механизм, запрещающий переопределять родительский метод Modify.

У меня при перекрытии методов выскакивает предупреждение в студии. У вас нет?

Есть sealed для методов, но он тут не подходит. Как же сделать?

Почему он не подходит? Костыль лучше? Ну... рефлексия даёт большие возможности, нор лучше всё-таки sealed.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы