问题描述:
比如如下2个类:
1 public class FirstClass
2 {
3 public static string first = "1";
4 public static string MethodName()
5 { //断点1
6 return SecondClass.Second;
7 }
8 }
9 public class SecondClass
10 {
11 public static string Second = "2"; //断点2
12 public static string RSecond()
13 {
14 return Second;
15 }
16 }
当外部方法调用FirstClass的MethodName的时候,断点2 比 断点1 优先执行。这个又是为什么呢?
这里面的原理通俗来讲就是:当一个函数开始执行前,CLR会做一些准备工作,其中有一项就是:检查这个函数中用到了哪些对象,他们的类型是什么,把这些类型信息加载到堆上。在本例中,当FirstClass.MethodName()被调用时,CLR首先发现这个函数内用到了SecondClass这个类型,那么它会把这个类型的相关信息先加载到堆上去。Second这个静态字段的初始化就是这个阶段完成的,因此断点2是在断点1前面。详细参见《CLR VIA C#》第4章第4节。
但是如果MethodName()方法里面调用的是SecondClass的静态方法,这些初始化就不会发生,这该怎么解释呢?
@荒芜: 当前framework版本对于静态字段的初始化是as lazy as possible的,详细解释和比较你可以看 http://csharpindepth.com/Articles/General/Beforefieldinit.aspx ,英文的,耐心点。
@水牛刀刀: 非常感谢!
看过这些文章以后,出现这种现象的主要原因是:
Type initializers 和 BeforFieldInit 这2个方面的理解。