为什么我的C#代码导致堆栈溢出

时间:2014-10-27 04:57:39

标签: c# unity3d

这是给出堆栈溢出的代码,它只发生了大约一半的时间,我不知道它为什么要这样做。从我所看到的情况来看,只有Coms(TopCom等)发生了大量的数字,所以大约5+,然后堆栈溢出。

public bool getConnected(int d) {
    if (topCom.connection != null) {
        if (d != topCom.connection.id) {
            if (topCom.connection.id == 0) {
                return true;
            } else if (topCom.connection.connected == true) {
                if (Development.instance.currentDos.buttons[topCom.connection.id].getConnected(id)) {
                    return true;
                }
            }
        }
    }

    if (leftCom.connection != null) {
        if (d != leftCom.connection.id) {
            if (leftCom.connection.id == 0) {
                return true;
            } else if (leftCom.connection.connected == true) {
                if (Development.instance.currentDos.buttons[leftCom.connection.id].getConnected(id)) {
                    return true;
                } 
            }
        }
    }

    if (rightCom.connection != null) {
        if (d != rightCom.connection.id) {
            if (rightCom.connection.id == 0) {
                return true;
            } else if (rightCom.connection.connected == true) {
                if (Development.instance.currentDos.buttons[rightCom.connection.id].getConnected(id)) {
                    return true;
                } 
            }
        }
    }

    if (botCom.connection != null) {
        if (d != botCom.connection.id) {
            if (botCom.connection.id == 0) {
                return true;
            } else if (botCom.connection.connected == true) {
                if (Development.instance.currentDos.buttons[botCom.connection.id].getConnected(id)) {
                    return true;
                } 
            }
        }
    }

    return false;
}

2 个答案:

答案 0 :(得分:1)

这种情况发生在递归函数中,在这些函数中,您没有基本条件来结束递归。你基本上一直在调用函数,直到你达到堆栈溢出为止。跟踪代码并弄清楚为什么它会无休止地调用它。

答案 1 :(得分:1)

这里的人们无法真正告诉你他们想要完成的事实是一种代码味道。

很大一部分原因是你的代码中有大量的嵌套。正如您现在发现的那样,嵌套条件会增加调试代码的难度。此外,您可以轻松地组合一些条件 - 任何顶级分支中的所有条件实际上可以组合成一个语句,如下所示:

if ((topCom.connection != null  && d != topCom.connection.id && topCom.connection.id == 0) ||  
    (topCom.connection.connected == true &&  
     Development.instance.currentDos.buttons[topCom.connection.id].getConnected(id))) 
{
    return true;
}

return false;

据我所知,具有执行相同功能的单独条件分支是没有意义的,例如:如果(a){return true; } else if(b){return true; }。只需将逻辑从else移动到原始if条件。

但是,我建议将部分或全部逻辑封装到一个单独的函数中,因为您似乎在每个连接上执行相同的逻辑。你可以像这样创建一个函数:

public bool ConnectionIsValid(connectionObject // replace with the actual type)
{
    if (topCom.connection != null  && d != topCom.connection.id && topCom.connection.id == 0)
        || (topCom.connection.connected == true 
        && Development.instance.currentDos.buttons[topCom.connection.id].getConnected(id))
        return true;

   return false;
}

这样你就可以在每个连接上调用ConnectionIsValid,而不是在每个连接的条件数上使用80-几行。

在此代码中发生StackOverflowException似乎也值得怀疑。除非您有与此代码中引用的任何对象相关的循环引用(在这种情况下,您使用setter访问器为同一个变量赋值的机会很大:     对象A.     {         组         {             this.A =价值;         }     }

总是会导致堆栈溢出,您可能已经在所包含的代码范围之外引入了某种递归。