-2

I coming back to C# programming after some years of HTML/ASP. I came across these lines and cannot find what it does. It is a method in a class:

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();
}

Is it calling itself until some of the other Returns happens?

What is happening here, never seen a method returning itself!? What is Returned, empty string or what...? Or maybe I just missed it before.

Maybe simple but puzzles me.

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
  • 1
    it's recursion looks like – Ehsan Sajjad Feb 28 '18 at 13:15
  • It will return result of "PeekNext()" method execution. It's typical for recursion, so i guess somehwere in the method body there is some if statement which will return actual value.\ – MajkeloDev Feb 28 '18 at 13:17
  • 2
    we can't tell without seeing the rest of the method. There surely are other return statements ending the recursion, otherwise this method would always result in a `StackOverflowException`. – René Vogt Feb 28 '18 at 13:17
  • Welcome to SO. Please follow https://stackoverflow.com/help/mcve to ask a better question. – Saleem Feb 28 '18 at 13:21

2 Answers2

0
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();
  • So it calls itself until some of the other Returns happens? – Per Welander Feb 28 '18 at 13:30
  • Please [edit](https://stackoverflow.com/posts/49030492/edit) your question instead of answering it. – Fildor Feb 28 '18 at 13:38
  • Yes, it calls itself (in more than one place) but there are other non-recursive returns so you would expect it to eventually terminate. However, using recursion like this in C# is weird because it does not support tail recursion (without tricks), and might cause a stack overflow. You can probably rewrite it using loops. – dumetrulo Feb 28 '18 at 13:39
  • Yes I suspected that Stackoverflow might happen if it never ends. I have not done it, found it in an help-object for IO handling. – Per Welander Feb 28 '18 at 13:43
0

Notwithstanding the fact that the method depends on external (class) variables, and should probably be refactored to take its dependencies as parameters, a non-recursive version could look as follows:

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;
}
dumetrulo
  • 1,993
  • 9
  • 11
  • Thanks, looks safer. This explains why I have never seen recursion before because I have never had any reason to do it. Learned 30+ years ago when I studied Standard C programming to never risk getting into a infinite loop. :-) And that the Last statement should Always be an exit point. No objects.methods() at that time only Functions(). – Per Welander Feb 28 '18 at 14:03