Q:

Implicit static constructor called before Main()

I have the following piece of codes.
class Program
{
    static void Main(string[] args)
    {
        Enterprise.Initialize("Awesome Company");
        // Assertion failed when constructor of 'Reg' class is disabled.
        Debug.Assert(Reg.Root == @"Software\Awesome Company");
    }
}

public static class Enterprise
{
    // Static Properties.
    public static string Company
    {
        get;
        private set;
    }
    // Static Methods.
    public static void Initialize(string company)
    {
        Company = company;
    }
}
public class Reg
{
    public static string Root = $@"Software\{Enterprise.Company}";
    
    // ctor.
    static Reg()
    {
        // Assertion failed when this constructor is disabled.
    }
}

When executed, the assertion passed. However, the assertion failed when the constructor for Reg class is disabled. On a closer look, I've found that the implicit constructor of Reg class is called before Main(). If the constructor of Reg class is explicitly defined, it will be called after Main().
Why such discrepancy between implicit and explicit constructor?

A:

This is a quirk of chained static class initialization.
From the ECMA C# Specifications

15.5.6.2 Static field initialization
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 (§15.5.6.1). Within a
partial class, the meaning of "textual order" is specified by
§15.5.6.1. If a static constructor (§15.12) 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.

Take special note of the last part, this is your problem, if you don't have a static constructor you have no control over when the field is initialized. In your test case they are being initialized before you call Enterprise.Initialize
In short, you shouldn't be relying on these rules, it's easy to make mistakes and is likely to cause weird issues.

