什么时候在C#中调用静态构造函数?


88

当我有一个包含静态构造函数的类时,是在第一次加载包含该类的程序集时或在该类的第一个引用被单击时调用该构造函数吗?

Answers:


93

首次访问该类时。

静态构造函数(C#编程指南)

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


6
有趣的是,它说“在创建第一个实例或引用任何静态成员之前”。实际调用还有一些余地。
蒂姆·巴拉斯

6
@TimBarrass由于规格圈一些其他要求的是“之前”实际上是“之前” -见乔恩斯基特的文章中对方的回答中引用- stackoverflow.com/a/1437372/477420
阿列克谢Levenkov

A static constructor is used to initialize any static data没有。最好用于static initializer初始化静态内容。
Yousha Aleayoub

41

尽管文档简单明了,但它并不像您期望的那么简单。乔恩·斯基特(Jon Skeet)的文章http://csharpindepth.com/Articles/General/Beforefieldinit.aspx详细介绍了此问题。

概要:

保证静态构造函数将在首次引用该类的成员之前立即执行-创建实例或类的静态方法/属性。

注意,静态初始化程序(如果没有静态构造函数)保证在首次引用特定字段之前的任何时间执行。


提到的文章现在在Jon Skeet的网站上:csharpindepth.com/Articles/General/Beforefieldinit.aspx
Sudhanshu Mishra

接下来的问题stackoverflow.com/questions/32525628/…演示了“立即”行为非常明显的情况。
Alexei Levenkov 2015年

1
我实际上只是在控制台应用程序的Main方法甚至开始执行之前就调用了静态构造函数的情况!
HerpDerpington

19

在类中使用任何东西之前,将调用静态构造函数,但是确切的时间取决于实现。

确保在访问第一个静态成员之前和创建第一个实例之前调用它。如果从不使用该类,则根本不能保证静态构造函数被调用。


2
如果发生这种情况,则不是“取决于实现”,如果该实现遵循ECMA C#规范:“静态构造函数的执行由在应用程序域内发生的以下第一个事件触发:[1]创建类。[2]引用了该类的任何静态成员。” (第17.11节,ecma-international.org / publications
standards /

1
@Luke:“静态构造函数执行的确切时机取决于实现” ondotnet.com/pub/a/dotnet/2003/07/07/staticxtor.html
Guffa

2
@Guffa:这可能是文章作者的解释,但是您不会在C#规范的Microsoft或ECMA / ISO版本中找到该措辞。
路加福音

1

如果从父类中调用了静态方法,则不会调用静态构造函数,尽管它是显式指定的。这是一个示例,如果调用b.methoda()则不调用b构造函数。

static void Main(string[] args)
{
    b.methoda();
}

class a
{
    public static void methoda()
    {
        //using initialized method data
    }
}

class b : a
{
    static b()
    {
        //some initialization
    }
}    

1

似乎有一个静态构造函数的陷阱,可以在其他地方回答,但花了一些时间才能消化成简单的解释。所有文档和说明都声称静态构造函数/初始化器在实例化第一个类或引用第一个静态字段之前已“保证”运行。当您尝试将静态单例放在创建自身实例(鸡/蛋)的类中时,就会出现问题。在这种情况下,静态构造函数最终在实例构造函数之后被调用-在我的情况下,实例构造函数包含依赖于某些静态数据的代码。

实例构造函数之后调用静态构造函数?

静态构造函数可以在非静态构造函数之后运行。这是编译器错误吗?

(对我来说,答案是将单例放在单独的类中,或者在需要之前在实例构造函数中手动初始化静态数据)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.