Как выполнить метод в базовом классе после полной инициализации child? - PullRequest
1 голос
/ 12 апреля 2019

Я реализовал следующую структуру:

public abstract class A
{
    protected A()
    {
        Test();
    }

    private void Test()
    {
        Console.WriteLine("2");
    }
}

public class B : A
{
    public B() : base()
    {
        Console.WriteLine("1");
    }
}

Когда я создаю экземпляр класса B, метод Test() выполняется перед вызовом конструктора в классе B.В моем случае этот метод должен выполняться после полной инициализации дочернего элемента.Возможный способ заставить это работать - сделать Test() доступным из B и вызвать его в конце конструктора.Это бы сработало, но если кто-то создаст другой подкласс A, есть вероятность, что он забудет вызвать метод.Мой вопрос заключается в том, существует ли в базовом классе более общее решение, позволяющее убедиться, что метод выполняется после полной инициализации дочернего элемента.

Ответы [ 3 ]

2 голосов
/ 12 апреля 2019

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

public abstract class A
{
    protected A(string data)
    {
        Test(data);
    }

    private void Test(string data)
    {
        Console.WriteLine(data);
    }
}

public class B : A
{
    public B() : base("1")
    {
        //some other initialization logic here
    }
}
2 голосов
/ 12 апреля 2019

Ответ - нет.

В .NET или C # нет ничего такого, что могло бы обеспечить вызов методов после выполнения всех конструкторов-потомков.

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

1 голос
/ 12 апреля 2019

Вы не можете напрямую "вставить" вызов метода перед вызовом конструктора базового класса, потому что он вызывает метод для неинициализированного объекта.Но вы можете использовать шаблон шаблона pattern:

abstract class A {

    protected A () {
        BeforeTest ();
        Test ();
    }

    protected abstract void BeforeTest ();

    private void Test () {
        Console.WriteLine ("2");
    }

}


class B : A {

    protected override void BeforeTest () {
        Console.WriteLine ("1");
    }

}


internal class Program {

    public static void Main (string [] args) {
        new B ();
    }

}

В качестве альтернативы вы можете сделать Test метод виртуальным:

abstract class A {

    protected A () {
        Test ();
    }

    protected virtual void Test () {
        Console.WriteLine ("2");
    }

}


class B : A {

    protected override void Test () {
        Console.WriteLine ("1");
        base.Test ();
    }

}


internal class Program {

    public static void Main (string [] args) {
        new B ();
    }

}

В обоих примерах выводится один и тот же результат:

1
2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...