为什么默认构造函数在静态构造函数之前执行?

时间:2018-10-27 03:00:26

标签: c# singleton console-application static-constructor

我想知道为什么我的静态构造函数输出default constructor Static Constructor,而不是相反地输出Static Constructor and Default constructor或仅输出Default constructor。当我使用静态构造函数时,它应该首先执行静态构造函数。但是,从下面的代码中,

第一个问题:为什么在静态构造函数之前调用默认构造函数?

class Program
{
    static void Main(string[] args)
    {
        var test = Single.S;
    }
    class Single{
        static readonly Single s = new Single();

        public static Single S{
            get { return s; }
        }
        private Single(){
            Console.WriteLine("Default");

        }
        static Single(){
            Console.WriteLine("staic");
        }
    }
}

第二个问题:静态单构造函数又如何被调用?

2 个答案:

答案 0 :(得分:1)

取决于Microsoft

  

static constructor用于初始化任何静态数据,或用于   执行只需要执行一次的特定操作。它   在创建第一个实例之前自动调用   引用了静态成员。

class SimpleClass
{
    // Static variable that must be initialized at run time.
    static readonly long baseline;

    // Static constructor is called at most one time, before any
    // instance constructor is invoked or member is accessed.
    static SimpleClass()
    {
        baseline = DateTime.Now.Ticks;
    }
}

在这种情况下,静态构造函数将在默认构造函数之前调用


但在这一行

static readonly Single s = new Single();

您正在使用“静态字段初始化”

  

类的静态字段变量初始值设定项对应于按其在类声明中出现的文本顺序执行的一系列分配。如果类中存在静态构造函数,则将在执行该静态构造函数之前立即执行静态字段初始化程序。

在这种情况下,静态字段初始化将在调用构造函数之前完成,

然后在默认构造函数

之前运行静态构造函数

但是运行时,它使用的是new Single(),因此要通过您的非静态构造函数路径。

这将导致在静态构造函数之前调用默认构造函数。

最后,您可以尝试执行此操作,然后它将执行 默认构造函数

之前的静态构造函数
private class Single
{
    private static readonly Single s;
    static Single()
    {
        Console.WriteLine("static");
        s = new Single();
    }
}

参考

答案 1 :(得分:0)

加载类时在这里发生的第一件事是

static Single s = new Single();

C#按照可见的顺序执行静态初始化程序。我不确定此排序点是否也适用于静态构造函数,但是从您的测试看来,静态初始化程序确实发生在静态构造函数之前。

无论如何,为了分配给静态Single,必须首先构造新的Single(),这意味着调用非静态构造函数。我不确定如果从非静态构造函数中读取Single.s会得到什么,但是我期望null或异常。