【问题标题】:Return syntax little strange [duplicate]返回语法有点奇怪[重复]
【发布时间】:2018-08-08 09:18:37
【问题描述】:

在使用了几年的 HTML/ASP 之后,我又回到了 C# 编程领域。 我遇到了这些行,找不到它的作用。 它是一个类中的一个方法:

private string PeekNext()
{
    if (pos < 0)
        // pos < 0 indicates that there are no more tokens
        return null;
    if (pos < tokens.Length)
    {
        if (tokens[pos].Length == 0)
        {
            ++pos;
            return PeekNext();
        }
        return tokens[pos];
    }
    string line = reader.ReadLine();
    if (line == null)
    {
        // There is no more data to read
        pos = -1;
        return null;
    }
    // Split the line that was read on white space characters
    tokens = line.Split(null);
    pos = 0;
    return PeekNext();
}

它是否会在其他一些 Return 发生之前调用自己?

这里发生了什么,从未见过返回自身的方法!? 什么是返回,空字符串或什么......? 或者我之前只是错过了它。

也许很简单,但让我很困惑。

【问题讨论】:

  • 它的递归看起来像
  • 它将返回“PeekNext()”方法执行的结果。它是递归的典型,所以我猜在方法体中有一些 if 语句将返回实际值。\
  • 如果没有看到其余的方法,我们就无法判断。肯定还有其他返回语句结束递归,否则这个方法总是会导致StackOverflowException
  • 欢迎来到 SO。请关注stackoverflow.com/help/mcve 提出更好的问题。

标签: c# return


【解决方案1】:
private string PeekNext()
    {
        if (pos < 0)
            // pos < 0 indicates that there are no more tokens
            return null;
        if (pos < tokens.Length)
        {
            if (tokens[pos].Length == 0)
            {
                ++pos;
                return PeekNext();
            }
            return tokens[pos];
        }
        string line = reader.ReadLine();
        if (line == null)
        {
            // There is no more data to read
            pos = -1;
            return null;
        }
        // Split the line that was read on white space characters
        tokens = line.Split(null);
        pos = 0;
        return PeekNext();

【讨论】:

  • 所以它会调用自己,直到其他一些 Return 发生?
  • edit您的问题而不是回答它。
  • 是的,它会调用自己(在不止一个地方),但还有其他非递归返回,因此您希望它最终会终止。但是,在 C# 中使用这样的递归很奇怪,因为它不支持尾递归(没有技巧),并且可能导致堆栈溢出。您可能可以使用循环重写它。
  • 是的,我怀疑如果 Stackoverflow 永远不会结束,它可能会发生。我没做过,在 IO 处理的帮助对象中找到的。
【解决方案2】:

尽管方法依赖于外部(类)变量,并且可能应该重构以将其依赖项作为参数,但非递归版本可能如下所示:

private string PeekNext()
{
    while (pos >= 0)
    {
        if (pos < tokens.Length)
        {
            if (tokens[pos].Length == 0)
            {
                ++pos;
                continue;
            }
            return tokens[pos];
        }
        string line = reader.ReadLine();
        if (line == null)
        {
            // There is no more data to read
            pos = -1;
            return null;
        }
        // Split the line that was read on white space characters
        tokens = line.Split(null);
        pos = 0;
    }
    // pos < 0 indicates that there are no more tokens
    return null;
}

【讨论】:

  • 谢谢,看起来更安全了。这就解释了为什么我以前从未见过递归,因为我从来没有任何理由这样做。 30 多年前,当我学习标准 C 编程时,我学到了永远不会陷入无限循环的风险。 :-) 最后一条语句应该始终是一个退出点。当时没有objects.methods()只有Functions()。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-14
  • 1970-01-01
相关资源
最近更新 更多