Quiz: Type Constructors (Answer)


Lots of good comments on my little quiz, seems it was too easy, everyone got it right!  

 

The first sample (in C# or VB) will print “17”.  To see why, check out the ILDASM for the .cctor (which, BTW, is identical in VB and C#):

 

  IL_0000:  ldc.i4.s   42

  IL_0002:  stsfld     int32 StaticConstructor.Foo::Value

  IL_0007:  ldc.i4.s   17

  IL_0009:  stsfld     int32 StaticConstructor.Foo::Value

  IL_000e:  ret

 

 

As you can see, the compilers emits the code for the inline static field initializer first (in this case the set to the value 42), then the user code for the .cctor (in this case the set to the value 17).   So that means the type constructor will always take precedence. 

 

As far as which “fix” is better.  Setting the static field in line is better from every angle.  It is less lines of code, easier to read and get right and, most importantly it is the best performing code with the most likelihood of getting even better in future versions of the CLR.  Check this out for more information: Perf penalty Static Constructor

 

Comments (1)

  1. Kevin Westhead says:

    Hmm, I seem to have made the same comment in both of your posts. I knew it sounded familiar. <g> I don’t agree about the "easier to read" bit though. The declarations could appear almost anywhere within the class or be obscured by XML comments, etc., whereas in a ctor they are nicely and neatly grouped together. I still maintain that a ctor is a perfectly sensible place to perform initialisation. This seems to be a recommendation, or maybe I’ve just mis-read you, for not using type ctors at all. So why make BeforeFieldInit optional, or why not allow it to be explicitly added in source code rather than relying on developers appreciating the subtle differences between the different types of initialisation options?