运行程序触发StackOverflowException,为何未执行构造函数就递归调用类字段?
问题原因分析
首先明确C#的实例初始化规则:类的实例字段会在构造函数体执行之前完成初始化,这是导致问题的核心。
你的代码触发的递归流程如下:
- 当执行
new ArrayTest1()时,程序会先初始化它的字段arrayTest2 = new ArrayTest2(),此时开始创建ArrayTest2的实例 - 创建ArrayTest2实例时,同样会先初始化它的字段
arrayTest1 = new ArrayTest1(),又回到创建ArrayTest1实例的步骤 - 这个循环会无限重复,每一次都卡在实例字段的初始化阶段,根本没机会进入构造函数的代码块执行
Console.WriteLine语句 - 每一次实例创建都会占用栈空间,循环次数过多后就会触发
StackOverflowException
简单来说,不是构造函数没执行,而是构造函数体还没来得及运行,就被字段初始化的递归循环卡死了。
修复示例
要解决这个问题,需要打破类之间的循环依赖,比如将字段初始化延迟到构造函数内,或者传递已有实例引用:
using System; public class Program { public static void Main() { Console.WriteLine("Hello World"); var arrayTest = new ArrayTest1(); } } public class ArrayTest1 { ArrayTest2 arrayTest2; public ArrayTest1() { Console.WriteLine($"{nameof(ArrayTest1)} Class Constructor Executed"); arrayTest2 = new ArrayTest2(this); } } public class ArrayTest2 { ArrayTest1 arrayTest1; public ArrayTest2(ArrayTest1 parentInstance) { Console.WriteLine($"{nameof(ArrayTest2)} Class Constructor Executed"); arrayTest1 = parentInstance; } }
内容的提问来源于stack exchange,提问作者Gowtham Raj
相关产品推荐
相关产品推荐

