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

当我有一个包含静态构造函数的类时,是在包含该类的程序集首次加载时调用该构造函数,还是在对该类的第一个引用被命中时调用该构造函数?

43169 次浏览

When the class is accessed for the first time.

Static Constructors (C# Programming Guide)

A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced.

It's not quite as simple as you might expect despite straightforward documentation. Jon Skeet's article http://csharpindepth.com/Articles/General/Beforefieldinit.aspx goes into this question in details.

Summary:

Static constructor is guaranteed to be executed immediately before the first reference to a member of that class - either creation of instance or own static method/property of class.

Note that static initilaizers (if there is no static constructor) guaranteed to be executed any time before first reference to particular field.

The static constructor is called before you use anything in the class, but exactly when that happens is up to the implementation.

It's guaranteed to be called before the first static member is accessed and before the first instance is created. If the class is never used, the static constructor is not guaranteed to be called at all.

In case static method is called from parent class, static constructor will not be called, althogh it is explicitly specified. Here is an example b constructor is not called if b.methoda() is called.

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


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


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

There seems to be a gotcha with static constructors that is answered elsewhere but took a while to digest into a simple explanation. All the docs and explanations claim the static constructor/intializers are "guaranteed" to run before the first class is instantiated or the first static field is referenced. The gotcha comes in when you try to put a static singleton in the class that creates an instance of itself (chicken/egg). In this case the static constructor ends up being called after the instance constructor - and in my case the instance constructor contained code that relied on some static data.

Static constructor called after instance constructor?

Static constructor can run after the non-static constructor. Is this a compiler bug?

(the answer for me was to put the singleton in a separate class or manually initialize the static data in the instance constructor before it is required)