С# Создавать конструктор базового класса после собственного конструктора?

Как я могу вызвать конструктор класса после Я назвал свой собственный конструктор?

Проблема заключается в том, что конструктор базового класса вызывает абстрактный метод (переопределенный в подклассе), которому необходимо получить доступ к переменной x, инициализированной в конструкторе подкласса?

Код короткого примера:

abstract class BaseClass
{
    protected string my_string;

    protected abstract void DoStuff();

    public BaseClass()
    {
        this.DoStuff();
    }
}

class SubClass : BaseClass
{
    private TextBox tb;

    public SubClass()
        : base()
    {
        this.my_string = "Short sentence.";
    }

    protected override void DoStuff()
    {
        // This gets called from base class' constructor
        // before sub class' constructor inits my_string
        tb.Text = this.my_string;
    }
}

Изменить: Основываясь на ответах, это, очевидно, невозможно. Существует ли автоматический способ вызова this.DoStuff(); для каждого объекта SubClass после его создания? Конечно, я мог бы просто добавить this.DoStuff(); после всех других строк в конструкторе подкласса, но имея около 100 из этих классов, он выглядит глупо. Любое другое решение, или я должен использовать ручной?

+15
28 янв. '13 в 13:10
источник поделиться
3 ответа

Вы не можете.

Кроме того, вы обычно не должны вызывать методы virtual в конструкторе. См. Этот ответ.


В зависимости от вашего фактического кода, а не от простого примера, который вы написали, вы можете передавать значения в качестве параметров базового конструктора и метода DoStuff. Например:

abstract class BaseClass
{
    private string my_string;

    protected abstract void DoStuff(string myString);

    public BaseClass(string myString)
    {
        this.my_string = myString;
        this.DoStuff(this.my_string);
    }
}

class SubClass : BaseClass
{
    private TextBox tb;

    public SubClass()
        : base("Short sentence.")
    {
    }

    protected override void DoStuff(string myString)
    {
        tb.Text = myString;
    }
}

Если это невозможно с вашим фактическим кодом, то выполнение задания DoStuff() будет выполняться. Также не забудьте закрепить свой класс SubClass, чтобы никто другой не смог ввести ошибки, изменив метод DoStuff в другое время.

+21
28 янв. '13 в 13:15
источник

Я бы не назвал абстрактного метода в конструкторе, поскольку может случиться так, что конструктор экземпляра, вызывающего метод, не выполнил

Когда вызывается виртуальный метод, фактический тип, который выполняет этот метод, не выбирается до времени выполнения. Когда конструктор вызывает виртуальный метод, возможно, что конструктор экземпляра, вызывающего метод, не выполнил. Чтобы устранить нарушение этого правила, не вызывайте виртуальные методы типа из конструкторов типов.

http://msdn.microsoft.com/en-us/library/ms182331%28v=vs.80%29.aspx

+4
28 янв. '13 в 13:14
источник

Есть ли причина, по которой вы не можете построить класс до того, как его конструктор действительно запустится? Это требует более высокого уровня ответственности за то, как создается производный класс и, вероятно, не является лучшей практикой, но, похоже, работает.

abstract class BaseClass {
    protected string my_string;

    protected abstract void DoStuff();

    public BaseClass() {
        this.DoStuff();
    }
}

class SubClass: BaseClass {
    TextBox tb;

    bool Constructed = false;
    void Constructor() {
        if (!Constructed) {
            Constructed = true;
            this.my_string = "Short sentence.";
        }
    }
    public SubClass()
        : base() {
        Constructor();
    }

    protected override void DoStuff() {
        Constructor();
        // This gets called from base class' constructor
        // before sub class' constructor inits my_string
        tb.Text = this.my_string;
    }
}
0
05 дек. '16 в 16:22
источник

Посмотрите другие вопросы по меткам или Задайте вопрос