I found static field initialization can behave differently. for the following code,
public class Class1
{
public static void Main()
{
Console.WriteLine("Main");
Test();
Console.ReadLine();
}
public static void Test(){
Console.WriteLine("Test");
Singleton.Instance.DoSomething();
}
}
public class Singleton
{
private static Singleton sInstance = new Singleton();
protected Singleton()
{
Console.WriteLine("Singleton Constructor");
}
public static Singleton Instance
{
get
{
return sInstance;
}
}
public void DoSomething(){}
}
in the debug build, it will print
Main
Test
Singleton Constructor
while in release build, it will print
Main
Singleton Constructor
Test
I checked the IL code generated of these 2 builds, there are nearly the same.
I wonder how this happens? And if it is a kind of JIT optimization in the release build, what is the motivation?
A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed only once. It is called automatically before the first instance is created or any static members are referenced. C# Copy. class SimpleClass { // Static variable that must be initialized at run time.
When a data member is shared among different instances it is imperative that data should be consistent among all the instances of the class. And also there is no way to call static constructor explicitly. Therefore the purpose of having a parameterized static constructor is useless.
Prerequisite: Constructors in C# Static constructors are used to initialize the static members of the class and are implicitly called before the creation of the first instance of the class. Non-static constructors are used to initialize the non-static members of the class.
Also, you can have a static constructor in a static class or a non-static class. A static constructor is used to initialize the static members of a class. The static constructor of a class is invoked the first time a static member of the class is accessed.
It completely depends on implementation when static initializers will execute . So the order could be different. But if you provide a static constructor those static initializers will always execute earlier. Hence the output will be in a consistent order.
From MSDN
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. If a static constructor (Section 10.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.
Add a static constructor in the Singleton
class
static Singleton() { }
I repro for the x86 jitter in the release build. This is by design, there is no guaranteed exact moment that the static class constructor runs, the only requirement is that it happens before any other methods in the class run. So the optimizer is permitted to rearrange code if that produces more efficient code. It does, it moves the cctor call all the way back to the Main() method. With the advantage that it now has more opportunities to optimize the remaining code.
In general, you want to avoid writing code in initialization expressions that has observable side-effects.
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