I’ve done some searching and I think the following code is guaranteed to produce output:
B.X = 7
B.X = 0
A.X = 1
A = 1, B = 0
static class B
{
public static int X = 7;
static B() {
Console.WriteLine("B.X = " + X);
X = A.X;
Console.WriteLine("B.X = " + X);
}
}
static class A
{
public static int X = B.X + 1;
static A() {
Console.WriteLine("A.X = " + X);
}
}
static class Program
{
static void Main() {
Console.WriteLine("A = {0}, B = {1}", A.X, B.X);
}
}
I’ve run this numerous times and always get the output above the code section; I just wanted to verify will it change? Even if textually, class A and class B are re-arranged?
Is it guaranteed that the first use of a static object will trigger the initialization of its static members, followed by instantiating its static constructor? For this program, using A.X in main will trigger the initialization of A.X, which in turn initializes B.X, then B() and after finishing the initialization of A.X, will proceed to A(). Finally, Main() will output A.X and B.X`.
Straight from ECMA-334:
And:
So the order is:
A.Xused, sostatic A()called.A.Xneeds to be initialized, but it usesB.X, sostatic B()called.B.Xneeds to be initialized, and it is initialized to 7.B.X = 7Bare initialized, sostatic B()is called.Xis printed (“7”), then it is set toA.X.Ahas already started being initialized, so we get the value ofA.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”).B, and the value ofA.Xis set toB.X+1.A.X = 1.Aare initialized, sostatic A()is called.A.Xis printed (“1”).Main, the values ofA.XandB.Xare printed (“1”, “0”).It actually comments upon this in the standard: