As you can see in the code below, the DoStuff() method is getting called before the Init() one during the construction of a Child object.
I\'m in a situation where I
DoStuff is abstract. Just call Init from the top of DoStuff.
Rather than using an abstract
method, which would require you to implement the method in all descendant classes, you might try:
public class Parent
{
public Parent()
{
PostConstructor();
}
protected virtual void PostConstructor()
{
}
}
public class Child : Parent
{
protected override void PostConstructor()
{
base.PostConstructor();
/// do whatever initialization here that you require
}
}
public class ChildWithoutOverride
{
/// not necessary to override PostConstructor
}
In WPF applications, you can postpone the invokation of DoStuff()
with the help of Dispatcher
:
abstract class Parent
{
public Parent()
{
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(this.DoStuff));
}
private void DoStuff()
{
// stuff, could also be abstract or virtual
}
}
However, it is not guaranteed that DoStuff()
will be called immediately after the constructor.
If you have a complex logic for constructing your objects then consider FactoryMethod pattern.
In your case I would implement it as a simple
public static Parent Construct(someParam)
method that takes some parameter and based on it decides which child class to instantiate.
You can remove your DoStuff()
method call from the constructor and call it inside Construct()
on the new instance.
Also, you should avoid virtual/abstract method calls in the constructors. See this question for more details: Virtual member call in a constructor
How about this:
abstract class Parent
{
public Parent()
{
Init();
DoStuff();
}
protected abstract void DoStuff();
protected abstract void Init();
}
class Child : Parent
{
public Child()
{
}
protected override void Init()
{
// needs to be called before doing stuff
}
protected override void DoStuff()
{
// stuff
}
}
Let me introduce a general solution using some C# features. Note that this solution does not require you to use a factory pattern or invoke anything after constructing the object, and it works on any class with just implementing an interface with a single method. First we declare an interface that our classes will have to implement:
public interface IInitialize {
void OnInitialize();
}
Next we add a static extension class for this interface, and add the Initialize method:
public static class InitializeExtensions
{
public static void Initialize<T>(this T obj) where T: IInitialize
{
if (obj.GetType() == typeof(T))
obj.OnInitialize();
}
}
Now, if we need a class and all of its descendants to call an initializer right after the object is fully constructed, all we need to do is implement IInitialize
and append a line in the constructor:
public class Parent : IInitialize
{
public virtual void OnInitialize()
{
Console.WriteLine("Parent");
}
public Parent()
{
this.Initialize();
}
}
public class Child : Parent
{
public Child()
{
this.Initialize();
}
public override void OnInitialize()
{
Console.WriteLine("Child");
}
}
public class GrandChild : Child
{
public GrandChild()
{
this.Initialize();
}
public override void OnInitialize()
{
Console.WriteLine("GrandChild");
}
}
The trick is that when a derived class calls the extension method Initialize
, that will suppress any calls not made from the actual class.