试图理解静态构造函数

5 c#

我试图理解对静态构造函数的需求.我找到的所有信息都没有回答我的问题.你为什么要这样做

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

与此相反

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

    // Static constructor is called at most one time, before any
    // instance constructor is invoked or member is accessed.
    //static SimpleClass()
    //{

    //}
}
Run Code Online (Sandbox Code Playgroud)


这不是其他问题的愚蠢,这是关于不接受参数的静态构造函数.

Geo*_*ica 5

需要显而易见:您希望为静态成员执行一些字段初始化.

逻辑上,如果你有这个类:

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


}
Run Code Online (Sandbox Code Playgroud)

你可以重写它以产生同样的效果:

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

    static SimpleClass () {
        baseline = DateTime.Now.Ticks;
    }   
}
Run Code Online (Sandbox Code Playgroud)

但相反,您可以在静态构造函数中执行更多操作,例如检查(使用反射)一些属性并向它们发出一些快速访问器/获取器,或者只是简单地通知其他系统您的类型已创建等.

来自Jeffrey Richter CLR通过C#书:

当C#编译器看到一个具有使用内联初始化的静态字段的类(BeforeFieldInit类)时,编译器将使用BeforeFieldInit元数据标志发出类的类型定义表条目.当C#编译器看到具有显式类型构造函数的类(Precise类)时,编译器将发出类的类型定义表条目,而不使用BeforeFieldInit元数据标志.其背后的基本原理如下:静态字段的初始化需要在访问字段之前完成,而显式类型构造函数可以包含任意代码,可以产生可观察到的副作用; 此代码可能需要在精确的时间运行.

显然,幕后发生的事情不止这些,我建议你通过C#阅读CLR的整章:"Type Constructors"

  • 好吧,它们并不完全相同 - 与只有静态字段初始值设定项的类相比,具有静态构造函数的类可以具有不同的初始化时序.见http://csharpindepth.com/Articles/General/Beforefieldinit.aspx (5认同)