Хочу создавать объекты, которые модифицируют переданную им строку. При этом нужно, чтобы никто из них не забывал проверять, а не пустая ли строка и передана ли она вообще.
=> создаю базовый абстрактный класс, в котором два метода:
* 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 для методов, но он тут не подходит. Как же сделать?