tags:

views:

111

answers:

5

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?

A: 
class A : B
{
   public A() : base()
   {
      base.doSomething();
   }
}

class B : C
{
   public B() : base()
   {

   }

   public void doSomething() { /* ... */ }
}

class C
{
   public C() { /* ... */ }
}

Execution Order should be:

  1. C::ctor()
  2. B::ctor()
  3. A::ctor()
  4. B::doSomething()
Aren
As I said, the method should be executed in the superclass, not in the subclass, you are just calling the superclass method in the subclass.
Thiado de Arruda
I suspect the OP is looking for a solution where the base class can ensure that some initialization runs after the type is fully instantiated. Otherwise, each derived class author must make sure to call the necessary initialization logic.
LBushkin
Thats exactly what I need :(
Thiado de Arruda
A: 

I'm not sure what you mean - can't you just call the code in the super class at the end of our last subclass constructor? Alternatively you could call it directly after instantiation.

class Program
    {
        static void Main(string[] args)
        {
            SubSub obj = new SubSub();                
            //obj.DoStuff();
            Console.ReadLine();
        }
    }

    class Super
    {
        public Super()
        {
            Console.WriteLine("Constructing Super");
        }
        public void DoStuff()
        {
            Console.WriteLine("Doin' stuff");
        }
    }

    class Sub : Super
    {
        public Sub()
        {
            Console.WriteLine("Constructing Sub");
        }
    }

    class SubSub : Sub
    {
        public SubSub()
        {
            Console.WriteLine("Constructing SubSub");
            DoStuff();
        }
    }

This will output:

Constructing Super 
Constructing Sub
Constructing SubSub 
Doin' stuff
Ryan Elkins
What I mean is that the code could be executed after complete construction of the object in the superclass, the subclass shouldnt know about it.
Thiado de Arruda
+2  A: 

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();
  }
}
Chris Taylor
If you go for two-pass create/initialize, I would advise using a factory method or Asbtract Factory to ensure that initialization semantics are not spread all over the code.
LBushkin
Ok, that is not exactly what I meant but it kinda helps me solve the problem, ty.
Thiado de Arruda
A: 
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();
    }
}
DanM
+1  A: 

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.

jkohlhepp
Do you know if Castle Windsor has something like that?
Thiado de Arruda
This is really more the domain of an AOP tool such as PostSharp (which you've now reminded me should've been included in my answer), but it might be possible to have Windsor do it. Never tried.
jkohlhepp