繁体   English   中英

在 Main() 之前调用的隐式静态构造函数

[英]Implicit static constructor called before Main()

我有以下一段代码。

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.
    }
}

执行时,断言通过。 但是,当Reg类的构造函数被禁用时,断言失败。 仔细观察,我发现Reg类的隐式构造函数在Main()之前调用。 如果明确定义了Reg类的构造函数,它将在Main()之后调用。

为什么隐式和显式构造函数之间存在这种差异?

这是链式静态类初始化的一个怪癖。

来自ECMA C# 规范

15.5.6.2 静态字段初始化

类的静态字段变量初始值设定项对应于以它们出现在类声明中的文本顺序执行的赋值序列(第 15.5.6.1 节)。 在部分类中,“文本顺序”的含义由 §15.5.6.1 指定。 如果类中存在静态构造函数(第 15.12 节),则在执行该静态构造函数之前立即执行静态字段初始值设定项。 否则,在第一次使用该类的静态字段之前的依赖于实现的时间执行静态字段初始值设定项。

请特别注意最后一部分,这是您的问题,如果您没有静态构造函数,您将无法控制字段何时初始化。 在您的测试用例中,它们在您调用Enterprise.Initialize之前被初始化

总之,你不应该依赖这些规则,很容易出错,很可能会导致奇怪的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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