Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
IcyWind
8 / 8 / 9
Регистрация: 19.09.2011
Сообщений: 272
#1

Порядок вызовов конструкторов в иерархии

12.10.2012, 11:16. Просмотров 2021. Ответов 2
Метки нет (Все метки)

Столкнулся с весьма интересной проблемой. У меня довольно обширная иерархия, но данный случай можно свести к паре классов:
есть базовый абстрактрый класс A с абстрактным методом Method()
есть производный класс B

Чтобы инстанцировать экземпляр класса B, необходимо в конструкторе выполнить метод Method(). Иерархия довольно большая, поэтому, чтобы в конструкторе каждого из класса не писать вызов того самого Method(), я начал вызывать его в конструкторе класса А. Ведь он же знает, что такой метод существует - вроде всё нормально. И радовался я этому факто до тех пор, пока метод Method() не стал зависеть от действий, которые выполняются в конструкторе класса B (для простоты, там создаётся список).
Сейчас порядок при конструировании объекта класса B такой:
-Вызывается конструктор класса А
-в конструкторе класса А вызывается абстрактный метод
-абстрактный метод выбрасывает исключение, что ссылка null

если бы сначала вызывался конструктор производного класса, а затем базового, всё бы работало. Можно ли так сделать?

и второй вариант решения проблемы - в каждом производном классе явно вызывать метод "Metod()"

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.10.2012, 11:16
Ответы с готовыми решениями:

Связывание вызовов конструкторов в цепочку
Добрый день. Подскажите, пожалуйста, как можно связать вызовы конструкторов в...

Использование конструкторов. Перегрузка конструкторов. Использование свойств
Помогите реализовать свойства, позволяющие осуществить проверку на допустимые...

Последовательность вызовов функций
Есть ли возможность запустить программу, работать с ней, а после получить...

Переполнение стека вызовов
using System; using System.Collections.Generic; namespace Lists { ///...

Отслеживание вызовов методов
Здравствуйте, имеется класс с методами: public class ClassA { ...

2
kolorotur
Эксперт .NET
10005 / 8403 / 2062
Регистрация: 17.09.2011
Сообщений: 14,466
12.10.2012, 11:43 #2
Цитата Сообщение от IcyWind Посмотреть сообщение
Можно ли так сделать?
Нельзя.

В целом у вас просматривается парочка антипаттернов, но хотелось бы глянуть на всю иерархию, чтобы более точно увидеть проблему и подсказать ее решение.
0
IcyWind
8 / 8 / 9
Регистрация: 19.09.2011
Сообщений: 272
12.10.2012, 11:48  [ТС] #3
Лучший ответ Сообщение было отмечено IcyWind как решение

Решение

Брошу версию после того, как я перенёс мой Method(), который на деле называется InitializeBasePoint() в конструктор каждого из наследников
Родитель:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public abstract class Shape
        {
           //public Shape()
           // {
           //     InitializeBasePoint(); //исключение...(
           // }
 
            protected static Pen _penPaint = new Pen(Color.BlueViolet);
            protected static SolidBrush _solidPaint = new SolidBrush(Color.BlueViolet);
            protected static Pen _penClear = new Pen (Color.White);
            protected static SolidBrush _solidClear = new SolidBrush(Color.White);
 
            protected Point BasePoint;
            protected const int StepToMove = 10; //const занимает память отдельно для каждого экземпляра? или по аналогии со static работает?
 
 
            public virtual void Draw() { _Draw(_penPaint, _solidPaint); }
            public abstract void MoveHorizontal(string s);
            public abstract void MoveVertical(string s);
            public abstract void Rotate(Point RotatePoint); //угол - 15?
            public abstract void Rotate();
            public virtual void Clear() { _Draw(_penClear, _solidClear); }
 
            protected abstract void _Draw(Pen _pen, SolidBrush _solid );
            
            protected abstract void InitializeBasePoint();
        }
    }
Вот тот наследник, который испортил мне всю малину)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
public class Polyline : Shape
        {
           private List<Point> _PointCollection;
           
           public Polyline(List<Point> PtCol)
           {
               _PointCollection = PtCol;
               InitializeBasePoint();
           }
           
 
            public override void MoveHorizontal(string s)
            {
                Clear();
                switch (s)
                {
                    case "right":
                        foreach (var item in _PointCollection)
                        {
                            item.MoveHorizontal("right");
                        }
                        break;
                    default:
                        foreach (var item in _PointCollection)
                        {
                            item.MoveHorizontal("left");
                        }
                        break;
                }
                Draw();
            }
 
            public override void MoveVertical(string s)
            {
                Clear();
                switch (s)
                {
                    case "up":
                        foreach (var item in _PointCollection)
                        {
                            item.MoveVertical("up");
                        }
                        break;
                    default:
                        foreach (var item in _PointCollection)
                        {
                            item.MoveVertical("down");
                        }
                        break;
                }
                Draw();
            }
 
            public override void Rotate(Point RotatePoint)
            {
                Clear();
                foreach (var item in _PointCollection)
                {
                    item.Rotate(RotatePoint);
                }
                Draw();
            }
 
            public override void Rotate() //будет ли сохраняться расстояние между точками?...вроде сохраняется:)
            {
                Clear();
                foreach (var item in _PointCollection)
                {
                    item.Rotate(BasePoint);
                }
                Draw();
            }
 
            protected override void _Draw(System.Drawing.Pen _pen, System.Drawing.SolidBrush _solid)
            {
                
                for (int i = 0; i < _PointCollection.Count-1; i++)
                {
                    g.DrawLine(_pen, _PointCollection[i].X, _PointCollection[i].Y, _PointCollection[i + 1].X, _PointCollection[i + 1].Y);
                }
            }
 
            public override void Clear()
            {
                base.Clear();
                foreach (var item in _PointCollection) //приходится делать 2 раза (в Rotate, move, чтобы при попытки рисования второго Polyline, пока существует первый, первый очищался правильно
                {
                    item.Clear();
                }
            }
 
      
 
            protected override void InitializeBasePoint()
            {
                //середина между первой и последней точками
                BasePoint = new Point((_PointCollection[_PointCollection.Count - 1].X + _PointCollection[0].X) / 2, (_PointCollection[_PointCollection.Count - 1].Y + _PointCollection[0].Y) / 2);
            }
А это пример "хорошего" наследника, который малину не портил
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public class Point : Shape
        {
            public int X { get; set; }
            public int Y { get; set; }
            public Point(int x, int y)
            {
                X = x;
                Y = y;
                InitializeBasePoint();
            }
       
            public override void MoveHorizontal(string s)
            {
                Clear();
                switch (s)
                {
                    case "right":
                        X += StepToMove;
                        break;
                    default:
                        X -= StepToMove;
                        break;
                }
                Draw();
            }
 
            public override void MoveVertical(string s)
            {
                Clear();
                switch (s)
                {
                    case "up":
                        Y -= StepToMove;
                        break;
                    default:
                        Y += StepToMove;
                        break;
                }
                Draw();
            }
 
            public override void Rotate(Point RotatePoint)
            {
                Clear();
                var absX = X - RotatePoint.X;
            
                var absY = Y - RotatePoint.Y;
                double newX = (RotatePoint.X + absX*Math.Cos(Math.PI/6) - absY*Math.Sin(Math.PI/6));
                double newY = (RotatePoint.Y + absX * Math.Sin(Math.PI / 6) + absY * Math.Cos(Math.PI / 6));
                
                X = newX % 1 < 0.5 ? (int)newX : (int)newX + 1;
                Y = newY % 1 < 0.5 ? (int)newY : (int)newY + 1;
                Draw();
            }
 
            public override void Rotate()
            {
                ;
            }
 
            protected override void InitializeBasePoint()
            {
                BasePoint = this;
            }
 
            protected override void _Draw(System.Drawing.Pen _pen, System.Drawing.SolidBrush _solid)
            {
                g.DrawEllipse(_pen, X, Y, 3, 3);
                g.FillEllipse(_solid, X, Y, 3, 3);
            }
        }
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.10.2012, 11:48

Перезагрузка конструкторов
Это то что надо сделать Осуществить перегрузку конструкторов для класса. ...

Набор конструкторов
Емеется множество и класс, в котором имеется свойство типа этого множества: ...

Скорость вызовов managed unmanaged
Подскажите пожалуйста, какие вызовы между управляемым и неуправляемым кодом...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru