【问题标题】:Why the default constructor executed before the static constructor?为什么默认构造函数在静态构造函数之前执行?
【发布时间】:2018-10-27 03:00:26
【问题描述】:

我想知道为什么我的静态构造函数输出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");
        }
    }
}

第二个问题:Static Single 构造函数怎么也被调用了?

【问题讨论】:

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


【解决方案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();
    }
}

参考文献

【讨论】:

    【解决方案2】:

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

    static Single s = new Single();
    

    C# 按照它们出现的顺序执行这样的静态初始化程序。我不确定这个排序点是否也适用于静态构造函数,但从您的测试来看,静态初始化器似乎确实发生在静态构造函数之前。

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

    【讨论】:

    • 最后一部分:这是一个 NullReferenceException。
    猜你喜欢
    • 2020-07-02
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 2011-10-23
    相关资源
    最近更新 更多