Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I execute some code in a superclass after all the subclasses have been constructed?

Tags:

c#

.net

oop

vb.net

Is there a way to do this in C#? I know that the subclass will call the superclass constructor before calling its own constructor, but what If I have some code on the superclass that should only be executed after all the subclasses constructors have been called?

like image 905
Thiago Padilha Avatar asked Apr 30 '10 19:04

Thiago Padilha


3 Answers

One way to achieve this would be to go for a 2 phase construct and initialize. So you construct the instances and then call an initialize method which invoked the base class Initialize in the appropriate order

class MyBase
{
  // Only if need to do some core initialization
  public MyBase()
  {
  }

  public virtual Initialize()
  {
    // do some initialization stuff here
  }
}

class MyDerived : MyBase
{
  // Only if need to do some core initialization
  public MyDerived()
  {
  }

  public override Initialize()
  {
    // do some initialization stuff here

    // Call the base class initialization function
    base.Initialize();
  }
}
like image 187
Chris Taylor Avatar answered Sep 25 '22 01:09

Chris Taylor


You could do the following, but it is risky (see my Edit below):

public class Parent
{
    public Parent()
    {
        Initialize();
    }

    protected virtual void Initialize()
    {
        // do stuff
    }
}

public class Child : Parent
{
    protected override void Initialize()
    {
        // do child stuff
        base.Initialize();
    }
}

Edit

As suggested in Terrence's comment below, this is a risky approach because Initialize() will be executed before Child's constructor is executed. If there are any fields initialized in Child's constructor, they won't be ready if they are used by Initialize(). This could cause confusing bugs.

A simple solution would be to give up on the Parent calling Initialize() and instead have the child classes call Initialize(). As others have suggested, another option would be to use the abstract factory pattern.

Here is a simple solution that uses a static factory method:

class Program
{
    static void Main()
    {
        Child.Create(() => new Child(5));
        Console.ReadKey();
    }
}

public abstract class Parent
{
    protected virtual void Initialize()
    {
        Console.Write(" is the number.");
    }

    public static TChild Create<TChild>(Func<TChild> childGetter)
        where TChild : Parent
    {
        var child = childGetter();
        child.Initialize();
        return child;
    }
}

public class Child : Parent
{
    private int _number;

    public Child(int number)
    {
        _number = number;
    }

    protected override void Initialize()
    {
        Console.Write(_number.ToString());
        base.Initialize();
    }
}
like image 44
devuxer Avatar answered Sep 25 '22 01:09

devuxer


There is nothing built into the C# language that lets you do this. However, using a creation pattern could support it. For example, the Abstract Factory pattern might be helpful here. The base factory would ensure that a method is called on the newly created base class once it has been instantiated as the concrete child type.

like image 41
RationalGeek Avatar answered Sep 23 '22 01:09

RationalGeek