Форум программистов, компьютерный форум, киберфорум
Наши страницы

C# для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.77
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 272
#1

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

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

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

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

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

и второй вариант решения проблемы - в каждом производном классе явно вызывать метод "Metod()"
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.10.2012, 11:16
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Порядок вызовов конструкторов в иерархии (C#):

Связывание вызовов конструкторов в цепочку - C#
Добрый день. Подскажите, пожалуйста, как можно связать вызовы конструкторов в цепочку не используя ключевого слова this. В Троелсене...

Использование конструкторов. Перегрузка конструкторов. Использование свойств - C#
Помогите реализовать свойства, позволяющие осуществить проверку на допустимые значения для данных класса. using System; using...

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

.NET 4.x Отслеживание вызовов методов - C#
Здравствуйте, имеется класс с методами: public class ClassA { public ClassA() { } ...

Перезагрузка конструкторов - C#
Это то что надо сделать Осуществить перегрузку конструкторов для класса. Особым методом реализовать метод run(), который будет...

Набор конструкторов - C#
Емеется множество и класс, в котором имеется свойство типа этого множества: enum Sides { right, left, up, down ...

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

В целом у вас просматривается парочка антипаттернов, но хотелось бы глянуть на всю иерархию, чтобы более точно увидеть проблему и подсказать ее решение.
0
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 272
12.10.2012, 11:48  [ТС] #3
Брошу версию после того, как я перенёс мой 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
Привет! Вот еще темы с ответами:

Функция подсцета рекурсивных вызовов - C#
Есть ли функция возвращающее число которое показывает который раз вызвана рекурсия функции/процедуры?

Создать функцию с подсчетом вызовов - C#
В общем, примитивная задача, решил её таким образом: using System; namespace ConsoleApplication43 { class Program { ...

Цепочка вызовов и передача аргументов - C#
Если делегат ссылается на цепочку методов (в примере ниже на методы one и two), то всем методам передается начальное значение аргумента?...

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


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

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

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