-
Григорьев Антон © (15.06.09 15:41) [0]Задача такая: есть базовый класс и много наследников от него. В конструкторе всех классов нужно выполнить одинаковую последовательность действий, только с одним параметром, правила вычисления которого разные в различных классах. Я засунул эти вычисления в конструктор базового класса, а вычисление параметра вынес в отдельную виртуальную функцию, которую перекрываю в наследниках. Получается примерно так:class BaseClass
{
public BaseClass(...)
{
int param = GetParam(...);
// Здесь реализация одинакового для всех классов алгоритма,
// в котором есть зависимость от param
}
protected virtual int GetParam(...)
{
// Вычисляем параметр по алгоритму для BaseClass
}
}
class AncestorClass : BaseClass
{
public AncestorClass(...)
: base(...)
{
// Инициализация полей AncestorClass
}
protected override int GetParam(...)
{
// Вычисляем параметры по алгоритму для AncestorClass
}
}
Возникает следующая проблема: реализация GetParam для AncestorClass использует поля этолго класса, которые инициализируются в его конструкторе. Но эта инициализация выполняется после того, как будет вызван базовый конструктор, поэтому AncestorClass.GetParam возвращает неправильное значение. К сожалению, самому выбрать момент вызова унаследованного конструктора, как в Delphi, в C# нельзя. Нет ли какого-то другого способа в базовом классе написать код так, чтобы он выполнялся сразу после того, как отработает код конструктора наследника? -
jack128_ (16.06.09 01:46) [1]
> Нет ли какого-то другого способа в базовом классе написать
> код так, чтобы он выполнялся сразу после того, как отработает
> код конструктора наследника?
инициализировать поля дочернего класса при объявлении??
class AncestorClass : BaseClass
{
int _field = 10; // на момент вызова GetParam поле _field уже будет проинициализировано
} -
Григорьев Антон © (16.06.09 09:06) [2]
> jack128_ (16.06.09 01:46) [1]
> инициализировать поля дочернего класса при объявлении??
К сожалению, мне это не подходит - инициализировать поля нужно значениями, переданными в качестве параметров в конструктор AncestorClass. -
Polevi © (16.06.09 09:47) [3]можно использовать PostSharp, если конечно нужно настолько сильно что возможно использование сторонних библиотек
-
Вариант (17.06.09 08:41) [4]Ну один из вариантов (правда на мой взгляд некрасиво, но дело вкуса) приведу ниже. Суть в применении ключевого слова params. Порядок вызова конструкторов не меняется, но можем создать конструктор с переменным числом параметров и соответственно виртуальные ( и перекрытые потом )методы с переменным числом параметров
Базовый классpublic class BS
{
public int i=-1;
public BS(params object [] list)
{
InitParam(list);
}
// инициализируем переменные, если надо и посчитаем
public virtual void InitParam(params object[] list)
{
i = (int)list[0];
MessageBox.Show(i.ToString());
}
}//end BS
наследник
public class BS1 : BS
{
public int x = 0;
public BS1(params object[] list) : base(list)
{
}
// инициализируем переменные, если надо и посчитаем
public override void InitParam(params object[] list)
{
i = (int)list[1];
x = (int)list[0];
MessageBox.Show(i.ToString(),x.ToString());
}
}//end BS1