在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禁用类的构造函数时,断言失败仔细观察,我发现Regclass 的隐式构造函数被称为before Main()如果Reg明确定义class 的构造函数,则将在之后调用它Main()

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

迈克尔·兰德尔(Michael Randall):

这是链接的静态类初始化的怪癖

来自ECMA C#规范

15.5.6.2静态字段初始化

类的静态字段变量初始值设定项对应于以文本顺序执行的分配顺序,这些赋值顺序出现在类声明中(第15.5.5.6.1节)。在局部类中,第15.5.6.1。节指定了“文本顺序”的含义。如果类中存在静态构造函数(第15.12节),则在执行该静态构造函数之前立即执行静态字段初始化程序。否则,将在首次使用该类的静态字段之前,在与实现相关的时间执行静态字段初始化程序。

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

简而言之,您不应该依赖这些规则,它很容易出错,并且很可能会引起奇怪的问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章