Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Конструктор в наследуемом классе.


Автор: Felixx 12.10.2011, 21:38
Доброго время суток. У меня имеется проблемка небольшая, подскажите пожалуйста что не так сделано?..
Суть проблемы такова:

Имеем абстрактный класс:
Код

public class PackageBuilder
{
    private byte[] buffer = new byte[] { };

     ..... куча методов.
}


1й наследник:
Код

public abstract class PBLoginPacket : PackageBuilder
{
        public PBLoginPacket()
        {
            try
            {
                this.WriteImpl();
            }
            catch (Exception e)
            {
                Console.Write(e.StackTrace);
            }
            ..... куча методов.
            
            protected abstract void WriteImpl();
        }
}


2й Наследник:

Код

class PROTOCOL_LOBBY_CREATE_ROOM_ACK : PBLoginPacket
{
        public PROTOCOL_LOBBY_CREATE_ROOM_ACK()
        {
            System.Console.WriteLine("test1");
        }

        protected override void WriteImpl()
        {
            System.Console.WriteLine("test2");
        }
}



В консоль выводитса:
test2
test1

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

Автор: mes 12.10.2011, 21:47
конструктор предка выполняется раньше конструктора наследника..

Автор: Felixx 12.10.2011, 21:50
Цитата(mes @ 12.10.2011,  21:47)
конструктор предка выполняется раньше конструктора наследника..

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

Автор: mes 12.10.2011, 22:02
Цитата(Felixx @  12.10.2011,  20:50 Найти цитируемый пост)
? метод вить абстрактный..

проблема не в методе, а в очередности выполнения констукторов..  если надо выполнить после конструктора наследника, то это можно выполнить только "извне"
то, есть тот кто создает объект, должен вызвать и этот метод.. 

Автор: math64 13.10.2011, 07:40
Я уже ответил в старом месте темы http://forum.vingrad.ru/index.php?showtopic=339714&view=findpost&p=2413254
Поясню, почему в конструкторе (C#) лучше не вызывать виртуальные методы:
Код

public abstract class A {
public A() { f(); }
protected abstract void f();
}
public class B : A {
public B() { buffer = new char[1]; }
protected overload void f() { buffer[0] = 'B'; } // Программа здесь вылетит, поскольку переменная buffer ещё не инициализирована
private char[] b;
}

В С++ поведение конструктора при вызове виртуальных методов безопаснее: если бы f() был бы не абстрактным, вызвался вы A::f().
Решение может быть например такое:
Код

public abstract class A {
public A() { f_forA(); }
protected virtual void f() {f_forA(); }
private void f_forA() { }
}
public class B : A {
public B() { buffer = new char[1]; }
protected overload void f() { f_forB(); }
private overload void f_forB() { buffer[0] = 'B'; }
private char[] b;
}


Добавлено @ 07:47
или такое:
Код

public abstract class A {
// Фабричный метод; поскольку A - абстрактный класс, закомментированный код не откомпилируется
// public static A create() { A a = new A(); a.f(); return a; }
// Конструктор защищен - создавать новые объекты через create
protected A() { }
protected abstract void f();
}
public class B : A {
public static B create() { B b = new B(); b.f(); return b; }
protected B() { buffer = new char[1]; }
protected overload void f() { buffer[0] = 'B'; }
private char[] b;
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)