Предположим, что наша система может выполнять действия и что для выполнения действия требуются некоторые параметры. Я определил следующий базовый класс для всех действий (упрощенных для вашего удовольствия чтения):
public abstract class BaseBusinessAction<TActionParameters>
: where TActionParameters : IActionParameters
{
protected BaseBusinessAction(TActionParameters actionParameters)
{
if (actionParameters == null)
throw new ArgumentNullException("actionParameters");
this.Parameters = actionParameters;
if (!ParametersAreValid())
throw new ArgumentException("Valid parameters must be supplied", "actionParameters");
}
protected TActionParameters Parameters { get; private set; }
protected abstract bool ParametersAreValid();
public void CommonMethod() { ... }
}
Только конкретная реализация BaseBusinessAction
знает, как проверить, что переданные ей параметры действительны, и, следовательно,
ParametersAreValid
- абстрактная функция. Тем не менее, я хочу, чтобы конструктор базового класса обеспечивал соблюдение того, что переданные параметры всегда действительны, поэтому я добавил
вызовите ParametersAreValid
конструктору, и я выдаю исключение, когда функция возвращает false
. Пока все хорошо, правда? Ну нет.
Анализ кода говорит мне: " не вызывает переопределяемые методы в конструкторах", что на самом деле имеет большой смысл, потому что, когда вызывается конструктор базового класса
конструктор дочернего класса еще не был вызван, и поэтому метод ParametersAreValid
может не иметь доступа к некоторой критической переменной-члену,
будет создан конструктор дочернего класса.
Итак, вопрос в следующем: как мне улучшить этот дизайн?
Добавляю ли параметр Func<bool, TActionParameters>
в конструктор базового класса? Если бы я сделал:
public class MyAction<MyParameters>
{
public MyAction(MyParameters actionParameters, bool something) : base(actionParameters, ValidateIt)
{
this.something = something;
}
private bool something;
public static bool ValidateIt()
{
return something;
}
}
Это будет работать, потому что ValidateIt
является статическим, но я не знаю... Есть ли лучший способ?
Комментарии очень приветствуются.