Richard Mitchell

Software Engineer - Red Gate Software
Engine programmer and factotum.

Which came first the static chicken or the static egg?

Published Wednesday, January 24, 2007 10:56 AM

Came across an interesting thing to do with static constructors in the course of the development of ANTS Profiler 3. We got around to talking about static constructors across multiple files and wondering what would happen if you attempted to create a circular reference of static initialisers. In the result you can see that the circular reference works exactly as you would expect. The static member variables being initialised to the default before any code got run so that wasn't interesting. However what if one of them is instantiated to a value and you refer to that value in the static method to instantiate another member variable (say for example opening a log file or something?) what would happen then?

So we come to the code:

using System;
namespace RedGate
{
  
partial class ChickenOrEgg
   {
        
static string egg = ValueOfChicken();
        
static string ValueOfEgg()
      {
           
return egg;
      }
     
static void Main(string[] args)
      {
        
Console.WriteLine("chicken={0} egg={1}", chicken, egg);
        
Console.WriteLine("Press any key...");
        
Console.ReadKey();
      }
   }
  
partial class ChickenOrEgg
   {
     
static string chicken = "Chicken"; // ValueOfEgg();
      static string ValueOfChicken()
     {
        
return chicken;
     }
   }
}

 

So what do we expect the output of this program to be? Well personally I would have thought...

 

chicken=Chicken egg=Chicken

The system noticing that the chicken member variable is set to be a static string so instantiating it first. But no the actual output of the program is...

chicken=Chicken egg=

So it's obvious that even though you would expect the static chicken string to be instantiated first as it has no dependencies that doesn't happen and if you look at the compiled code in Reflector you can see what the static constructor actually is.

static ChickenOrEgg()
{
      ChickenOrEgg.egg = ChickenOrEgg.ValueOfChicken();
      ChickenOrEgg.chicken =
"Chicken";
}


So here's a warning to all of you out there, don't assume anything about the order in which your static initialisers get called as it will only cause pain.

The answer to the initial question - the static chicken :)

Comments

No Comments
You need to sign in to comment on this blog

















<January 2007>
SuMoTuWeThFrSa
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910
Virtual Exchange Servers
 Microsoft now supports running Exchange Server 2007 in server virtualization environments, not just on... Read more...

Virtualizing Exchange: points for discussion
 With the increasing acceptance of the use of Virtualization as a means of providing server... Read more...

Encouraging .NET Reflector Add-ins
 Jason Haley is well-known for the resources he's provided to developers who wish to extend Reflector's... Read more...

Using .NET Reflector Add-ins
 .NET Reflector by itself is great, but it really comes into its own with the help of some add-ins. Here... Read more...

Unique Experiences!
 You'd have thought that a unique constraint was an easy concept - Not a bit of it; it can cause a lot... Read more...