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

C# 为什么我的C代码会导致堆栈溢出,c#,unity3d,C#,Unity3d,这是导致堆栈溢出的代码,它只发生了大约一半的时间,我不知道它为什么会这样做。从我所看到的情况来看,只有当COM(TopCom等)有大量的数字时才会发生这种情况,所以大约5+左右,然后堆栈溢出 public bool getConnected(int d) { if (topCom.connection != null) { if (d != topCom.connection.id) { if (topCom.connection.id == 0)

这是导致堆栈溢出的代码,它只发生了大约一半的时间,我不知道它为什么会这样做。从我所看到的情况来看,只有当COM(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;
}

这发生在递归函数中,您没有结束递归的基本条件。基本上一直调用该函数,直到达到堆栈溢出。。追踪你的代码,找出它为什么不断地调用自己

事实上,这里的人不能真正知道你想要完成什么,这是一种代码味道

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

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;
就我所能想象的,没有必要让单独的条件分支执行相同的函数,例如if(a){return true;}或者if(b){return true;}。只需将逻辑从else if移到原始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 { 设置 { 这个.A=值; } }


这通常会导致堆栈溢出,很可能您在包含的代码范围之外引入了某种递归。

您是否尝试调试代码?我们甚至不知道您的结构的定义-我们所知道的是,是的,代码可能会以无限循环结束(当当前实例和一个
topCom
形成循环时)-我无法给出一个合理的解决方案,除了传递一个带有已访问节点的
HashSet
,以便您可以检测loops。在过去的四个小时里,我一直在使用堆栈跟踪和调试语句。我只是试图清理代码以进行显示。然后您必须重新考虑您的算法(我们对此一无所知)-您必须找到某种方法来打破图形中的循环-我告诉过您一种可能性(使用访问节点的哈希集)但是应该一直到它为真或为假,然后追溯到上,或者我的堆栈跟踪有一半的时间是这样说的。如果我理解你说的,如果做一个返回中间函数,它会一直在函数中运行?是的,但是它会给出一个大的NullReferenceException。编写预编辑不应该给出NullReference异常,除非我犯了错误。and(&&&)运算符的一个重要方面是,如果它在任何特定范围内遇到一个错误语句,它将停止操作,因此语句a!=null&&a!=12将永远不会抛出NullReferenceException,因为如果a为null,将永远不会检查!=12。