C# 为什么当我尝试实例化一个类实例时,会得到StackOverFlowException?

C# 为什么当我尝试实例化一个类实例时,会得到StackOverFlowException?,c#,C#,每当我实例化一个类的实例时,我总是得到StackOverFlowException。我知道这与A.b字段是从类A派生的类型这一事实有关。但为什么会导致异常呢 static void Main(string[] args) { A a = new A(); // exception } class A { private B b = new B(); } class B:A {} 谢谢因为A引用了A类B,B类派生自A。由于构造函数链接,B的构造函数调用A的构造函数,导致创

每当我实例化一个类的实例时,我总是得到StackOverFlowException。我知道这与A.b字段是从类A派生的类型这一事实有关。但为什么会导致异常呢

static void Main(string[] args)
{
     A a = new A(); // exception
}

class A 
{
    private B b = new B();
}

class B:A {}

谢谢

因为A引用了A类B,B类派生自A。由于构造函数链接,B的构造函数调用A的构造函数,导致创建一个新的B实例,该实例将持续到永恒或StackOverflowException。

因为B是从A继承的,所以每次创建A时,都会创建一个B,反过来创建另一个B。实际上,您已经创建了一个无休止的类创建循环。

因为构造函数是递归调用的

当您创建A的实例时,它将创建B的内部实例。。。。猜什么,创建一个B的内部实例,猜什么,创建一个B的内部实例,猜什么,创建一个B的内部实例


这是因为B构造函数在递归的A构造函数上运行。堆栈溢出。

以下是引擎盖下发生的情况

创建的新实例 因此,它为私有字段B创建了一个实例B B源于A,因此有它自己的字段B。此时,它返回到步骤2并重复,直到发生堆栈溢出
因为你有一个循环引用

为了得到一个B,你必须得到一个a 为了得到A,你必须得到B

因此,它向下延伸


要解决此问题,请不要初始化私有字段。

如果希望子类了解任何派生类型,请使用泛型。在CSLA.NET框架中,这一点非常重要

public class A<T> where T : A<T>
{

}

public class B : A<B>
{

}

请注意,A不引用B,但您可以在方法等的基础级别封装派生类型。

因为如果我尝试在A的构造函数中初始化A.B字段,也会引发相同的异常,所以我假设唯一的解决方法是根本不初始化A.B字段?我尝试过实例化您的代码,但它不起作用->A=新A;对不起,在我使用这个小模式的所有地方,基类都是抽象的——你实例化并使用B,而不是A;其中B是从A派生的,这是有效的。您只能得到基类引用。因为这是一个非常做作的问题。。。我认为这是一个巨魔tbh-但我喜欢一个关于自我引用的问题的想法,它引用了它所在的网站。我想不出一个现实生活中的例子,任何人都会或倾向于这样做——可能是因为我缺乏想象力,