编译器在编译的时候,会事先分析所须要的静态字段,若是这些静态字段所在的类有静态的构造函数,则忽略静态字段的初始化,不然先进行静态字段的初始化。对类的静态成员初始化的顺序取决于在Main函数中的引用顺序,先引用到的先进行初始化,但若是类的静态成员的初始化依赖于其它类的静态成员,则会先初始化被依赖类的静态成员。而带有静态构造函数的类的静态字段,只有在引用到的时候才进行初始化。html
接下来,用实例来对以上的一段总结性的描述逐句分析:函数
一、编译器在编译的时候,会事先分析所须要的静态字段,若是这些静态字段所在的类有静态的构造函数,则忽略静态字段的初始化,不然先进行静态字段的初始化。
spa
==无静态构造函数:上图中实例的执行流程就是红色数字标记的顺序,首先,在编译器进行编译时,发现Main主函数中会用到A类的静态字段X,因此,会在程序开始执行以前去对能用到的静态字段进行初始化(在无静态构造函数的前提下);B类中的静态字段没有初始化的缘由是编译时没有发现用到此静态字段;静态字段在IL中标记为BeforeFliedInit;htm
将上图中的普通构造函数换为静态构造函数会是什么效果呢?
blog
==静态构造函数:当类A中有静态的构造函数时,其静态字段再也不提早去初始化,而是当调用时才进行初始化;当执行完静态字段后,会紧接着去执行静态构造函数中的代码块;值得一说的是,若是A类中有一个静态的方法,当Main函数调用时则先执行A类的静态构造函数,再去执行静态方法;get
二、对类的静态成员初始化的顺序取决于在Main函数中的引用顺序,先引用到的先进行初始化(这个就不用写例子了,对于两个相同状态的类(都含有静态构造函数或都没有),其中类静态字段的初始化的顺序都是按照其在Main函数中调用时的顺序执行的),固然若是过一个有静态构造函数,另外一个没有静态的构造函数的话,那就另当别论了!编译器
三、若是类的静态成员的初始化依赖于其它类的静态成员,则会先初始化被依赖类的静态成员。
博客
==首先,上图的代码中A类和B类都含有普通的构造函数,而且主程序中都用到了这两个类中的静态字段,那么它们的静态字段就会在主程序运行以前进行初始化,而后当有多个静态字段时,他们的执行顺序就是按照主程序中调用的顺序来执行!如上图:先初始化Y,再初始化Xit
四、若是类的静态成员的初始化依赖于其它类的静态成员,则会先初始化被依赖类的静态成员
编译
==如上图,在编译器编译时,检测到会用到A类的静态字段,那么就会在Main主函数运行以前对A类的X字段进行初始化,可是X字段中又用到了B类的Y字段,因此就会先初始化B类中的Y字段,再初始化A类的X字段!也就是先初始化被依赖的静态字段。
五、而带有静态构造函数的类的静态字段,只有在引用到的时候才进行初始化。
这里才是博客中主要的,静态构造函数的做用就是不让静态字段在主程序运行以前进行初始化,而是当主程序调用它时才执行,而且紧接着执行该字段索在类的静态构造函数中的代码
==上例中由于A类和B类都含有静态的构造函数,全部就避免了其类中静态字段的提早初始化,当调用用时才执行,而且在上例中A类的X字段又依赖B类的Y字段(由于都是普通的构造函数,因此不会提早执行,而是用到时才执行),因此当程序到达A的X字段时就会去调用B类的Y字段(紧接着执行B类的静态构造函数),回来以后再继续执行A类的静态够走啊函数!
这个博客中写得也很是的详细:博客地址网址
2013-9-22更新
==当第一次调用静态字段时,就会执行全部静态字段,并执行静态构造函数,下次再调用其余静态字段时,就直接取便可,没必要在执行一遍User类
==只要使用此类,例如实例化,就会执行类中的静态字段。