先看一道常见题目,如下代码的执行结果是什么?安全
class A { public static int X = B.Y + 1; static void Main(string[] args) { Console.WriteLine(X); } } class B { public static int Z = 10; public static int Y; static B() { Console.WriteLine(Z); Y = A.X + 1; } }
1、定义多线程
由名称可知,静态构造函数(也称为类型构造函数)包含“静态”和“构造函数”两个特色。第一个特色决定了它与静态函数相似,只能使用静态成员;第二个特色决定了它与构造函数相似,具备初始化做用,而且没有返回值。函数
与构造函数(针对实例对象)不一样的是,静态构造函数(针对类)只执行一次,而且是在第一个实例对象建立前被调用,因此它能够用于那些只须要执行一次的操做;并且它不容许有public等修饰符,由程序自动调用,不能被外界调用。spa
总结:静态构造函数用于初始化任何静态数据,或者用于执行仅需执行一次的操做;在建立第一个实例对象或者引用任何静态变量以前,将自动调用静态构造函数。线程
特色:对象
一、静态构造函数既没有访问修饰符,也没有参数。blog
二、在建立第一个实例或引用任何静态成员以前,将自动调用静态构造函数来初始化类。同步
三、没法直接调用静态构造函数。 string
四、在程序中,用户没法控制什么时候执行静态构造函数。it
五、线程安全。
关于线程安全须要特别说明一下,因为程序可能在多线程环境下运行,也就是可能出现同时多个线程准备执行静态构造函数的状况。CLR确保这个过程是安全的,实际上调用静态构造函数的线程须要先得到一个互斥线程同步锁,若是有多个线程试图执行类型的静态构造函数,只有一个线程能得到该锁;得到锁的线程完成初始类型初始化操做,其它线程只能等待;当初始化完成,等待的线程被唤醒,而后发现静态构造函数已经被执行过,就不会再执行。
2、语法
public class StaticTester { static StaticTester() { } }
3、做用
用于初始化静态成员。有时候咱们会从配置文件读取一些值做为静态变量,相似这样:
public class StaticTester { private static readonly string key = ConfigurationManager.AppSettings["key"]; private static readonly string value = ConfigurationManager.AppSettings["value"]; static StaticTester() { } }
若是要读取的配置信息比较多,并且要加入一些逻辑判断,那么能够这样:
public class StaticTester { private static readonly string key; private static readonly string value; static StaticTester() { key = ConfigurationManager.AppSettings["key"]; if (string.IsNullOrEmpty(key)) { throw new Exception("key变量未被正确配置!"); } value = ConfigurationManager.AppSettings["value"]; if (string.IsNullOrEmpty(value)) { throw new Exception("value变量未被正确配置!"); } } }
4、执行顺序
1. 运行时,优先对静态变量进行初始化。
2. 若是有静态构造函数,那么在建立第一个实例对象或者引用任何静态变量以前,调用静态构造函数。
3. 其它操做。