Do you have any idea, why the following code:
public class A
{
public static int i = B.i + 1;
}
public class B
{
public static int i = A.i + 1;
}
Having:
int aa = A.i;
int bb = B.i;
Says that aa = 2 (!!!) and bb = 1.
I have a STACK OVERFLOW in my brain!!! As far as i understand, recursion stops on static methods, but why? If you remake int i to the getters (to debug and understand why on earth it works like that), you get the stack overflow exception.
No doubt execution is happening like so:
The B.i static initializer runs first, and sets B.i = A.i + 1. Since A.i hasn't been initialized yet, A.i is equal to default(int), which is 0. B.i gets the value 1.
The A.i static initializer runs second, and sets A.i = B.i + 1 = 2.
Since static initializers run in an undefined order, you might find that a different field is 2 each time when you run it, or that they switch when you make other structural changes to your code. However, one should always wind up as 2, and one should always be 1.
P.S. This has nothing to do with polymorphism.
EDIT: For some further understanding of the timing of static initializers and constructors, you might want to examine this relevant portion of the C# specification.
A field is not like a property getter. It just stores the data, not any operation. In fact, the initialization will be moved to another method (static constructor, .cctor) which will initialize static variables in the class.
At the beginning, both will equal to 0. Before you access A.i for the first time, the method .cctor for class A runs. It tries to access B.i for the first time which will cause execution of the static constructor of class B. .cctor of B will try to access A.i but since it's not the first time a field is being accessed, static constructor of A will not run anymore. It just fetches the current value of A which is still 0. Consequently, B.i will be equal to 1 when B..cctor finishes execution and control is returned to A..cctor. It will see the value B.i and adds 1 to it and stores it in A.i. Thus, A.i will be equal to 2 (1+1) and B.i will be equal to 1.
The only guarantee you get is that the static constructor will be called before any static member of that class is accessed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With