Another question on SO inspired me to try this code in C#:
class Program
{
static Program()
{
new Program().Run();
}
static void Main(string[] args) { }
void Run()
{
System.Console.WriteLine("Running");
}
}
This prints “Running” when run.
I actually expected the compiler to complain about this. After all, if the class has not yet been initialized by the static constructor; how can we be sure that it is valid to call methods on it ?
So why does the compiler not restrict us from doing this ? Is there any important usage scenarios for this ?
Edit
I am aware of the Singleton pattern; the point in question is why I can call a method on the instance before my static constructor finishes. So far JaredPar’s answer has some good reasoning about this.
It is allowed because not allowing it would be a lot worse. Code like this would deadlock badly:
You are of course pointing a loaded gun at your foot.
This behavior is documented in the CLI Spec (Ecma 335) Partition II, Chapter 10.5.3.2 “Relaxed guarantees”:
A type can be marked with the attribute beforefieldinit (§10.1.6) to indicate that the guarantees specified in §10.5.3.1 are not necessarily required. In particular, the final requirement above need not be provided: the type initializer need not be executed before a static method is called or referenced.
[Rationale: When code can be executed in multiple application domains it becomes particularly expensive to ensure this final guarantee. At the same time, examination of large bodies of managed code have shown that this final guarantee is rarely required, since type initializers are almost always simple methods for initializing
static fields. Leaving it up to the CIL generator (and hence, possibly, to the programmer) to decide whether this guarantee is required therefore provides efficiency when it is desired at the cost of consistency guarantees.
end rationale]
The C# compiler indeed emits the beforefieldinit attribute on a class: