C# 完全退出递归函数

C# 完全退出递归函数,c#,recursion,unity3d,while-loop,C#,Recursion,Unity3d,While Loop,我有一个关于我做的递归函数的问题。有什么方法可以在到达“return arraydenodes”行后完全退出函数?因为我使用VisualStudio跟踪代码执行,一旦执行到上面提到的行,它就会从while循环返回到堆栈(或者我认为是这样)的“else”中。正因为如此,path.Add行一直在执行,给了我一个不同的结果。这是密码 private Node[] checkTheOtherDude(Node start, Node endpadre, Node end, Node previousNo

我有一个关于我做的递归函数的问题。有什么方法可以在到达“return arraydenodes”行后完全退出函数?因为我使用VisualStudio跟踪代码执行,一旦执行到上面提到的行,它就会从while循环返回到堆栈(或者我认为是这样)的“else”中。正因为如此,
path.Add
行一直在执行,给了我一个不同的结果。这是密码

private Node[] checkTheOtherDude(Node start, Node endpadre, Node end, Node previousNodeTemp)
{

    //Debug.Log(previousNode);
    while(endpadre != null && !stop)
    {

        if (!Physics.Linecast(end.transform.position, endpadre.transform.position)) // end y endpadre se ven?
        {
            previousNode = endpadre;
            Node newParent = endpadre.padre;

            checkTheOtherDude(start, newParent, end, previousNode); // chequear n y n padre padre

        }
        else
        {
            //previousNode = endpadre;
            path.Add(end);
            path.Add(previousNode);
            end = endpadre;
            Node newParent = end.padre;
            checkTheOtherDude(start, newParent, endpadre, previousNode);
        }
    }       
        stop = true;
        path.Add(end);
        path.Add(start);
        path.Reverse();
        arraydeNodes = path.ToArray();
        return arraydeNodes;                  
}

似乎我已经解决了这个问题,问题(或者至少我认为)是while条件,将其更改为
while(endpadre!=null&&&!stop&&endpadre!=start)
我缺少
endpadre!=开始
,这样当结束节点与开始节点相同时,循环将右结束。

是,只需更改这两行即可

checkTheOtherDude(start, newParent, end, previousNode);
checkTheOtherDude(start, newParent, endpadre, previousNode);


这些将使它一路返回

while循环之后的代码可以执行多次(与递归级别一样多)吗
另外,
path.Reverse()
将被多次调用,这是我不确定您是否真正想要的。

要阻止该代码执行,可以执行以下操作:

if (!stop)
{
     stop = true;
     path.Add(end);
     path.Add(start);
     path.Reverse();
     arraydeNodes = path.ToArray();
}

return arraydeNodes;      
我已经玩了一点,修改了你的代码
试试这个:

private Node[] checkTheOtherDude(Node start, Node endpadre, Node end, Node previousNodeTemp)
{
    if (endpadre == null)
    {
        path.Add(end);
        path.Add(start);
        path.Reverse();
        arraydeNodes = path.ToArray();
        return arraydeNodes;   
    }
    else if (!Physics.Linecast(end.transform.position, endpadre.transform.position)) // end y endpadre se ven?
    {
        previousNode = endpadre;
        Node newParent = endpadre.padre;

        return checkTheOtherDude(start, newParent, end, previousNode); // chequear n y n padre padre

    }
    else
    {
        //previousNode = endpadre;
        path.Add(end);
        path.Add(previousNode);
        end = endpadre;
        Node newParent = end.padre;
        return checkTheOtherDude(start, newParent, endpadre, previousNode);
    }                   
}

尝试使用测试数据运行此操作(只有少数节点)。然后在第一次单击后检查路径,然后调试第二次单击。你应该能够看到问题所在。可能存在无限递归(节点括号中的循环)

如果设计正确,应该没关系。如果您遇到了麻烦,那么您的递归方法做得太多(关注点分离)或者结构不正确。当最内部的调用退出时,它应该自然返回堆栈的所有部分,即在方法的正确返回结构内。当在方法末尾有递归退出时,在每个递归调用到达其退出点之前,您不会退出。这意味着穿越一切。在递归方法开始时考虑退出条件,因为我不知道函数应该做什么,对于这个特定的情况,这可能是错误的,但是一般来说,你想<代码>返回< /代码>递归调用的结果。首先,我不知道为什么你需要返回节点[]。它位于参数列表中,因此将自动更新。一旦可以消除节点[]作为返回值,就可以返回一个布尔停止以返回顶部。我不同意Rory的回答,因为我已经编写了很多递归代码,在某些情况下,您需要返回一个变量来停止处理。while循环之后的代码可以执行多次(与您的递归级别一样多)吗?同样
path.Reverse()
将被多次调用,这是我不确定您是否真的想要的。每次单击,代码都会运行并生成路径。第一次单击效果很好,第二次单击(在同一程序运行期间)会抛出堆栈溢出错误。尽管如此,我开始认为问题可能来自代码中的另一个位置,即使错误显示在这些行中。请尝试使用测试数据(只有少数节点)运行此操作。然后在第一次单击后检查路径,然后调试第二次单击。你应该能够看到问题所在。也许有无限递归(节点括号中的循环)我设法解决了它,这实际上是另一回事,查看我上面编辑的帖子。无论如何谢谢你的帮助。嗯,我真的做到了哈哈,这正是你所说的。每次我点击,代码都会运行并生成路径。第一次单击效果很好,第二次单击(在同一程序运行期间)会抛出堆栈溢出错误。@JackBauer您不应该让递归方法产生副作用。这是你的主要问题。您的递归方法应该计算一个值并返回它,将它们需要的任何数据作为参数,并将所有计算作为返回值返回。正如您所看到的,过程中的状态突变会造成巨大的混乱。
private Node[] checkTheOtherDude(Node start, Node endpadre, Node end, Node previousNodeTemp)
{
    if (endpadre == null)
    {
        path.Add(end);
        path.Add(start);
        path.Reverse();
        arraydeNodes = path.ToArray();
        return arraydeNodes;   
    }
    else if (!Physics.Linecast(end.transform.position, endpadre.transform.position)) // end y endpadre se ven?
    {
        previousNode = endpadre;
        Node newParent = endpadre.padre;

        return checkTheOtherDude(start, newParent, end, previousNode); // chequear n y n padre padre

    }
    else
    {
        //previousNode = endpadre;
        path.Add(end);
        path.Add(previousNode);
        end = endpadre;
        Node newParent = end.padre;
        return checkTheOtherDude(start, newParent, endpadre, previousNode);
    }                   
}