简体   繁体   中英

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM