如何在C#中避免StackOverflowException?

时间:2012-12-24 09:01:33

标签: c# stack-overflow

我对C#还不熟悉,并认为我会从教程here.开始

我已经完成了前3个,并且正在研究更多关于C#类以及可以使用它们的各种方法。然后我突然意识到我的所有代码都在一个类(MainForm,因为我正在使用SharpDevelop),我应该尝试更好地组织它。但是,当我尝试在其他类中引用代码时,我得到一个StackOverflowException。我已经实例化了这个类(例如CheckAnswers checkanswers = new checkanswers;),出了什么问题?如果需要,我可以发布代码,但我的猜测是这是一个很容易诊断的n00b错误。

修改

代码 - https://docs.google.com/open?id=0B9vVcIham8NHMGlNaDk3MTZ6ejA

有很多。这只是我自己编写的代码,而不是表单配置。

3 个答案:

答案 0 :(得分:3)

你在这里进行相互递归。

在MainForm中,你隐式调用第23行的CheckAnswers构造函数(它是一个非静态变量的初始化,这意味着它将在构造MainForm时运行)。
在CheckAnswers中,您以类似的方式创建MainForm实例(第193行)。

这将导致堆栈溢出 - MainForm创建一个CheckAnswers对象,该对象创建一个MainForm对象,该对象创建一个CheckAnswers对象......

编辑:如果您需要在类之间进行双向通信(在大多数情况下我建议不要这样做),这将无效。 CheckAnswers对象包含对不同实例 MainForm的引用,MainForm实例也是如此。这根本不起作用(以及导致无限递归) 执行所需操作的一种方法是将MainForm实例发送到CheckAnswers构造函数,然后在第23行中使用“this”作为构造函数的参数,并使用该参数初始化mainform(在CheckAnswers中)。像这样:

public partial class MainForm : Form
{
    CheckAnswers checkanswers;
    ...
    public MainForm()
    {
        checkanswers = new CheckAnswers(this);
        ...
    }
}
public class CheckAnswers // Not sure why you inherit MainForm here, but it's not a good idea, as someone already stated
{
    MainForm mainform;

    public CheckAnswers (MainForm main)
    {
        mainform = main;
    }
    ...
}

答案 1 :(得分:1)

CheckAnswers类派生自MainForm类。 因此,当您调用CheckAnswers类的构造函数时,它会使用基类的所有内部成员(MainForm)创建此类的实例。这就是为什么再次调用这行代码的原因:

第23行:CheckAnswers checkanswers = new CheckAnswers();

同样,创建了实例,并且一次又一次地调用这行代码,直到发生StackOverflow异常。

基本上,此代码表示与代码中相同的问题:

class BaseClass
{
    DerivedClass myObject = new DerivedClass(); // this is a recursive call
}

class DerivedClass : BaseClass
{   
}

答案 2 :(得分:0)

要进行通信,您应该将现有对象的实例作为参数传递,而不是每次都创建一个新实例(否则将不会在具体对象之间进行通信)。

所以这是一个代表你需要做什么的想法的例子:

public class CheckAnswers
{
    MainForm mainform;
    public CheckAnswers (MainForm  form)
    { 
        this.mainform = form;
    }

   ...
}

在MainForm类中,您必须将“self”作为参数传递给CheckAnswers的构造函数,如下所示:

CheckAnswers checkanswers = new CheckAnswers(this);
相关问题