Is the order of static class initialization in C# deterministic?

Straight from ECMA-334:

17.4.5.1:If a static constructor (§17.11) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.”

And:

17.11: The execution of a static constructor is triggered by the first
of the following events to occur within an application domain:

  • An instance of the class is created.
  • Any of the static members of the class are referenced.

If a class contains the Main method (§10.1) in which execution begins, the static constructor for that class
executes before the Main method is called. If a class contains any static fields with initializers, those
initializers are executed in textual order immediately prior to executing the static constructor (§17.4.5).

So the order is:

  • A.X used, so static A() called.
  • A.X needs to be initialized, but it uses B.X, so static B() called.
  • B.X needs to be initialized, and it is initialized to 7. B.X = 7
  • All static fields of B are initialized, so static B() is called. X is printed (“7”), then it is set to A.X. A has already started being initialized, so we get the value of A.X, which is the default value (“when a class is initialized, all static fields in that class are first initialized to their default value”); B.X = 0, and is printed (“0”).
  • Done initializing B, and the value of A.X is set to B.X+1. A.X = 1.
  • All static fields of A are initialized, so static A() is called. A.X is printed (“1”).
  • Back in Main, the values of A.X and B.X are printed (“1”, “0”).

It actually comments upon this in the standard:

17.4.5: It is possible for static fields with variable initializers to be observed in their default value state. However, this is strongly discouraged as a matter of style.

Leave a Comment