Конференция ".Net" » Порядок инициализации полей в C#
 
  • Григорьев Антон © (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

 
Конференция ".Net" » Порядок инициализации полей в C#
Есть новые Нет новых   [134427   +35][b:0][p:0.002]