子级完全初始化后,如何在基类中执行方法?

时间:2019-04-12 07:59:49

标签: c# .net constructor abstract-class

我实现了以下结构:

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 个答案:

答案 0 :(得分:2)

答案是否定的。

.NET或C#内置没有任何东西可以确保在所有后代构造函数执行后,会被调用。

另一种方法是某种形式的工厂模式,其中您的类基本上只是为您提供另一个已正确设置的实例,并调用了所有必需的方法。

答案 1 :(得分:2)

之所以不能完成,是因为构造方法的初始化程序无法正常工作。相反,您可以选择将一些参数传递给基本构造函数,这些参数可能特定于您的子类,例如

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 :(得分:1)

在调用基类的构造函数之前,您不能直接“插入”方法调用,因为它是在未初始化的对象上调用方法。但是您可以使用模板方法模式:

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