2

I implemented the following structure:

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

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

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

When I create an instance of class B, the method Test() is executed before the constructor calls in class B. In my case, this method should run after the child is fully initialized. A possible way to make it work would be to make Test() accessible from B and call it at the end of its constructor. That would work but if someone creates another subclass of A , there is a chance that he forgets to call the method. My question is whether there is a more general solution in the base class to make sure that the method is executed after a child is fully initialized.

Nico Schreiner
  • 397
  • 5
  • 13

3 Answers3

2

The answer is no.

There is nothing built into .NET or C# that can make sure methods are being called after all descendant constructors have executed.

A different approach would be some form of the factory pattern, where your class would basically just provide you with another instance that has been correctly set up, and all required methods called.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
2

That can't be done cause constructor initializer doesn't work that way. Rather you can choose to pass some parameter to base constructor, parameters which may be specific to your child class like

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
    }
}
Rahul
  • 76,197
  • 13
  • 71
  • 125
  • It could be delegate, which is called before `Test()` and contains inherited class specific initialization. Then inherited class constructor can be left empty. But some features (e.g. setting value to getter-only auto-properties) won't work. – Sinatr Apr 12 '19 at 08:18
1

You can't directly "insert" a method call before calling constructor of base class, because it's calling a method on an uninitialized object. But you can use the template method 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 ();
    }

}

Alternatively, you can make Test method virtual:

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 ();
    }

}

Both examples outputs the same result:

1
2
trollingchar
  • 760
  • 2
  • 6
  • 18