Click here to monitor SSC

Jason Crease

Test Engineer - Red Gate Software

Order of Construction

Published Monday, June 02, 2008 4:05 PM

 

For me, inheritance is often a headache.  In particular, in what order is everything initialized?  Consider this short C# program.   It creates an instance of Dog, which derives from Animal.  Both Dog and Animal have an instance constructor, a class initializer (aka a static constructor), an instance variable, and a static variable. 

using System;


namespace CtorOrder
{
    
class Animal
    {
        
public int instanceAnimal Program.Print("Animal.instanceAnimal");
        
public static int staticAnimal Program.Print("Animal.staticAnimal");
        
public Animal()
        
{
            Console.WriteLine
("Animal constructor");
        
}
        
static Animal()
        
{
            Console.WriteLine
("Animal class constructor");
        
}
    }
    
class Dog Animal
    {
        
public int instanceDog Program.Print("Dog.instanceDog");
        
public static int staticDog Program.Print("Dog.staticDog");
 
        
public Dog()
        
{
            Console.WriteLine
("Dog constructor");
        
}
        
static Dog()
        
{
            Console.WriteLine
("Dog class constructor");
        
}
    }
 
    
class Program
    {
        
public static int Print(string s)
        
{
            Console.WriteLine
(s);
            
return 0;
        
}
        
static void Main(string[] args)
        
{
            Dog d 
= new Dog();
            
Console.WriteLine("\nPress enter to continue");
            
Console.ReadLine();
        
}
    }
}

There are eight activities here:

  1. Dog instance constructor
  2. Dog class constructor
  3. Dog instance variable
  4. Dog static variable
  5. Animal instance constructor
  6. Animal class constructor
  7. Animal instance variable
  8. Animal static variable

The question is: ‘In what order are the eight activities run?’  Try working it out.  Anyway, the answer is:

  1. Dog static variable
  2. Dog class constructor
  3. Dog instance variable
  4. Animal static variable
  5. Animal class constructor
  6. Animal instance variable
  7. Animal instance constructor
  8. Dog instance constructor

There are two things I find surprising about this:

  1. Why do static constructors run from most derived class to least derived class, i.e. Dog then Animal?
  2. Why do instance variables get initialized before calling the parent’s instance constructor?

The answer to question 1 is that Dog’s class initializer has to be run since we are running Dog’s instance constructor, but execution of any type's class initializer method will not trigger automatic execution of any class initializer methods defined by its base type.  Indeed, why should it?

 

The answer to question 2 is complicated.  Constructing instance fields in the most derived class first is the only way to ensure that readonly fields are initialized and then not changed.  Check out Eric Lippert’s blog for a decent explanation: http://blogs.msdn.com/ericlippert/archive/2008/02/15/why-do-initializers-run-in-the-opposite-order-as-constructors-part-one.aspx

You need to sign in to comment on this blog

About Jason Crease

Jason Crease joined Red-Gate in 2006, and works as a software tester in the .NET division. He is currently working on Reflector Pro.
<June 2008>
SuMoTuWeThFrSa
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345
Automated Script-generation with Powershell and SMO
 In the first of a series of articles on automating the process of building, modifying and copying SQL... Read more...

Converting String Data to XML and XML to String Data
 We all appreciate that, in general, XML documents or fragments are held in strings as text markup. In... Read more...

Geek of the Week: Don Syme
 With the arrival of F# 3.0 Microsoft announced a wide range of improvements such as type providers that... Read more...

How to Document and Configure SQL Server Instance Settings
 Occasionally, when you install identical databases on two different SQL Server instances, they will... Read more...

What's the Point of Using VARCHAR(n) Anymore?
 The arrival of the (MAX) data types in SQL Server 2005 were one of the most popular feature for the... Read more...