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?
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();
}
}
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();
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With