During my research into the best way to build a Singleton in C# I stumbled across the following article where there is a brief mention that in C++
“The C++ specification left some ambiguity around the initialization
order of static variables.”
I ended up looking into the question and found this and this. Where basically the point (as far as I understand) is that the initialization order of static variables in C++ is undefined. Ok I guess so far so good, but then I wanted to understand the following statement that the article later makes
“Fortunately, the .NET Framework resolves this ambiguity through its
handling of variable initialization.”
So I found this page where they say
The static field variable initializers of a class correspond to a
sequence of assignments that are executed in the textual order in
which they appear in the class declaration.
and give the example of
using System;
class Test
{
static void Main() {
Console.WriteLine("{0} {1}", B.Y, A.X);
}
public static int F(string s) {
Console.WriteLine(s);
return 1;
}
}
class A
{
static A() {}
public static int X = Test.F("Init A");
}
class B
{
static B() {}
public static int Y = Test.F("Init B");
}
the output must be:
Init B
Init A
1 1
“Because the rules for when static constructors execute (as defined in
Section 10.11) provide that B’s static constructor (and hence B’s
static field initializers) must run before A’s static constructor and
field initializers.”
But where I am confused is that my understanding was that the initialization order of static variables in these examples would be based on when a method or field within the class was first invoked, which is in turn based on the execution order of the block of code (this case left to right). IE: Completely independent of where – or the order – of the class declaration. Yet by my interpretation of that article it says its as a result of the order of declaration of those classes, which my testing doesn’t back up?
Could someone please clarify this (and the point the article is trying to make) for me and perhaps provide a better example that illiterates the behaviour described?
This means that within the same class, static fields are initialized in order of appearance in the source code. For example:
When it’s time for the static fields to be initialized,
Xis guaranteed to be initialized beforeY.This means that the static constructor and member initialization for each class will run in evaluation order when expressions that access these classes appear¹. The relative order of appearance of the class definitions in source code does not play any role, even if they appear in the same source file (which they most certainly are not obliged to do). For example:
Assuming that neither
AnorBhas already been statically initialized, order of evaluation guarantees that all the fields ofBwill be initialized before any field ofA. The fields of each class will be initialized in the order specified by the first rule.¹ for the purposes of this discussion I am ignoring the existence of
beforefieldinit.