By running this simple code:
class Program
{
class MyClassWithStatic
{
public static int Number = SomeService.GetData();
static MyClassWithStatic()
{
Console.WriteLine("static ctor runs");
}
}
class SomeService
{
public static int GetData()
{
Console.WriteLine("GetDataRuns");
return 42;
}
}
static void Main(string[] args)
{
InitService();
var value = MyClassWithStatic.Number;
Console.WriteLine(value);
}
private static void InitService()
{
Console.WriteLine("InitServiceRuns");
}
}
The output on my machine is this:
InitServiceRuns
GetDataRuns
static ctor runs
42
Meaning first the InitService method is called, then the static field of the MyClassWithStatic is initialized and then the static constructor is called (in fact by looking at this in ILSpy and IlDasm we can see that the initialization of the static fields happens at the beginning of the cctor)
There is nothing interesting at this point, everything makes sense, but when I remove the static constructor of the MyClassWithStatic (so MyClassWithStatic becomes this, and everything else remains as before)
class MyClassWithStatic
{
public static int Number = SomeService.GetData();
}
The output is this:
GetDataRuns
InitServiceRuns
42
This means by removing the static constructor the static fields are initialized earlier. Since the initialization is a part of the static constructor (I tell this by looking into it with ildasm) the effect is basically that the static constructor is called earlier.
So here is the question:
Can someone explain this behaviour? What can be the reason for this?
Is there any other thing which can change when the static constructor is called? (E.g. attaching a profiler or running it in IIS, etc.) (I compared debug, release mode, x86,x64 and all show the same behavior)
Some general things:
-This was in a .NET 4.6 console application. I also switched to .NET 2 (should run with a different clr, and the behaviour is the same, it doesn't make any difference)
-I also tried this with .NET core: both with and without a cctor the InitService method is called first.
-Now I'm absolutely aware of this page:
The user has no control on when the static constructor is executed in the program.
And I also know that in a static constructor there are many things you shouldn't do. But unfortunately I have to deal with a code where this part is outside of my control and the difference I described makes a huge difference. (And I also went through many C# cctor related SO questions..)
(And Question nr3:) So isn't the whole thing I described a little bit problematic?