C#中静态构造函数与字段初始化顺序:为何不会无限递归?
为什么这段C#代码不会触发无限递归?
先看示例代码:
class Program { static void Main() { Console.WriteLine (Foo.X); } // 3 } class Foo { public static Foo Instance = new Foo(); //static field 1 public static int X = 3; //static field 2 Foo() => Console.WriteLine (X); // 0 }
核心原因是C#运行时会确保类型的静态初始化过程只执行一次,且初始化期间不可重入,具体执行逻辑如下:
- 当
Main方法第一次访问Foo.X时,CLR会启动Foo类型的静态初始化流程。 - 按照静态字段的声明顺序,先处理
Instance = new Foo():调用Foo的实例构造函数。 - 在实例构造函数里访问
X时,X还没完成初始化,所以输出默认值0。 - 此时
Foo的静态初始化已经处于"正在进行"的状态,CLR会标记这个状态,因此在实例构造函数执行过程中,不会再次触发Foo的静态初始化——也就是说,不会重新去初始化Instance字段,自然不会再次调用new Foo(),也就不会出现无限递归。 - 实例构造函数执行完成后,
Instance字段赋值完毕,接着初始化X为3,最后Main方法输出3。
简单来说:类型的静态初始化是单趟有序执行的,且初始化过程中不会重复触发自身的静态初始化,所以不会无限创建Foo实例。
内容的提问来源于stack exchange,提问作者saner
相关产品推荐
相关产品推荐

