Обязательный вызов функции базового класса в классе-наследнике
Подскажите, есть ли в C# средство, путем которого я могу обязать в перегруженных методах класса-наследника вызывать методы класса-родителя?
Моя ситуация: есть алгоритм как базовый класс, есть несколько его реализаций. Параметры одни и те же. При этом нужно делать предварительную проверку параметров, которую логично запихать в базовый класс. Как мне сделать, чтобы при написании новой реализации алгоритма я не забыл включить эту проверку, то есть обязать вызвать функцию проверки?
И еще: какие есть возможности для того, чтобы уйти от дублирования кода? Ведь по сути вызов проверки в каждой реализации алгоритма есть дублирование, что не есть хорошо. Жду советов профессионалов :)
И еще: какие есть возможности для того, чтобы уйти от дублирования кода? Ведь по сути вызов проверки в каждой реализации алгоритма есть дублирование, что не есть хорошо.
На мнение профессионала не претендую, но что мешает использовать делегаты?
Пример:
{
public delegate int DMyAlg(int param);
DMyAlg _alg;
public MyAlg(DMyAlg Alg)
{
_alg = Alg;
}
public int Run(int x)
{
if (x > 0) return _alg(x);
else return _alg(x);
}
}
class Program
{
static void Main(string[] args)
{
MyAlg m1 = new MyAlg(x => x * x);
MyAlg m2 = new MyAlg(x => x * x - x);
Console.WriteLine(m1.Run(10));
Console.WriteLine(m2.Run(10));
Console.ReadLine();
}
}
принудительно вызывайте функцию базового класса:
[code=c#]
class Base
{
public virtual void PrintMes()
{
Console.WriteLine("This is Base Message");
}
}
class Child : Base
{
public override void PrintMes()
{
base.PrintMes(); // вызов функции базового класса
Console.WriteLine("child Message");
}
}
[/code]
также, конструктор базового класса вызывается перед конструктором дочернего класса и в нем можно также оформлять какие то общие моменты, в том числе вызвать методы базового класса, при условии что они не перегружены в дочерних классах, т.к. в этом случае будет срабатывать метод дочернего класса (если создается дочерний объект);
{
public void DoSomeWork(string a, int b)
{
// проверяем a
// проверяем b
DoSomeWorkInternal(a, b);
}
protected abstract void DoSomeWorkInternal(string a, int b);
}
public class Derived : Base
{
protected override void DoSomeWorkInternal(string a, int b)
{
// работаем с корректными a и b
}
}
спасибо за правильный ответ, но есть но, у меня. можешь объяснить принципиальную разницу? как минимум я не врубаюсь почему в дочернем классе, в реализации метода DoSomeWorkInternal уже работаем с корректными 'а' и 'б'? разве не надо явно вызвать метод базового абстрактного класса DoSomeWork(string a, int b)
?
псп за ответ, только вот я не уверенна, что данный подход даст гарантию того, что метод DoSomeWork будет вызван вовремя, возможно это из за не понимания общей картины.
Что значит вовремя? Клиенты иерархии классов Base только его (DoSomeWork) и могут вызывать - ко внутренней реализации у них нет доступа.
ну если доступ только к этой функции, то убедил. а как внутренние запускаются? извини за тупые вопросы, я такого еще не видела (
Как правило внутренние вызовы не требуют проверки аргументов.
вопрос исчерпан. спасибо.
{
public void DoSomeWork(string a, int b)
{
// проверяем a
// проверяем b
DoSomeWorkInternal(a, b);
}
protected abstract void DoSomeWorkInternal(string a, int b);
}
public class Derived : Base
{
protected override void DoSomeWorkInternal(string a, int b)
{
// работаем с корректными a и b
}
}
Да, я предполагал такое решение, спасибо, теперь знаю, что оно правильное :)
А нельзя ли такого эффекта добиться путем проставления атрибутов? Вопрос может быть лишен смысла, потому что я еще не понял, как они используются. Ну кроме Serializable.
Как я это видел: функцию проверки в базовом классе помечаем неким атрибутом, который программисту будет говорить, где ее рекомендуется вызывать. Такое вообще возможно?
Как я это видел: функцию проверки в базовом классе помечаем неким атрибутом, который программисту будет говорить, где ее рекомендуется вызывать. Такое вообще возможно?
Атрибуты нужны не программистам, они нужны программам, обрабатывающим метаданные. Например в .NET 4 появились Code Contracts (реализация идеи контрактного программирования с помощью атрибутов), посмотрите на них.