递归调用是否适用于goto?

时间:2014-08-01 20:41:50

标签: c# recursion

我有一个方法,我必须多次调用它才能得到一个结果,我想知道在这种情况下Recursive调用工作为goto

虚拟代码:

public int DummyMethod()
{
    string token;
    int result = -1;

    token = GetNewToken();

    Stopwatch stopwatch = Stopwatch.StartNew();
    while (result == -1)
    {
        if (stopwatch.Elapsed >= TimeSpan.FromSeconds(350)) { 
            //This is related to some logic as the token for the website 
            //expires after 350 seconds.
            result = DummyMethod();
            continue; //DO I NEED TO USE contunue ? or the recursive 
                      //call broke the method (as if i used goto)
        }

        result = GetResultFromWebSite(token);
    }

    return result;
}

4 个答案:

答案 0 :(得分:1)

您应该使用

return DummyMethod();

这是一个尾调用(编译器可以把它变成一个goto)。

这是一个很好的例证单一进入/单一回归"口头禅失败。

但是,我很确定你可以将它构建到循环中并避免递归:

public int DummyMethod()
{
    Stopwatch stopwatch = Stopwatch.StartNew();
    string token = GetNewToken();
    int result;
    do
    {
        if (stopwatch.Elapsed.TotalSeconds >= 350) {
            token = GetNewToken();
            stopwatch.Restart();
        }

        result = GetResultFromWebSite(token);
    } while (result == -1);

    return result;
}

答案 1 :(得分:1)

我认为你这一切都错了,你绝对不应该试图弄清楚你的令牌是否已经过期。这应该是服务器告诉你的东西。如果它是通过异常来实现的,你可以这样做:

public int DummyMethod(int retries = 0)
{
    string token;
    try 
    {
        token = GetNewToken();
        return GetResultFromWebSite(token);
    }
    catch (Exception e)
    {
        if (retries < 4) // or whatever max you want - you probably shouldn't hardcode it
        {
            return DummyMethod(++retries);
        }
        throw new Exception("Server ain't responding");
    }
}

在这种情况下,通常最好进行最大重试次数,之后您将放弃并显示错误消息。

答案 2 :(得分:0)

在我看来,你想知道如何停止递归。这通常是在结果清除并返回的情况下完成的,而不再调用递归函数。这样就可以停止对递归方法的无休止调用,并且递归将结束。你没有使用goto,就像你根本不应该使用goto;)

答案 3 :(得分:0)

不,递归调用不等同于goto语句。

您甚至不需要使用递归来解决问题。如果您在循环中将GetNewToken拨打电话,则可以检查结果并使用continue执行另一次迭代,如果您没有获得所需的结果。如果确实得到了所需的结果,可以调用GetResultFromWebSite并立即返回结果。