tags:

views:

114

answers:

4

What am I missing in GetLowestLevelFoo? Why do I get the answer A instead of D?

    public class Foo
    {
        public string Name { get; set; }
        public Foo ChildFoo { get; set; }
    }

    [TestFixture]
    public class Recursion
    {
        [Test]
        public void Test()
        {
            Foo foo = new Foo
            {
                Name = "A",
                ChildFoo = new Foo
                {
                    Name = "B",
                    ChildFoo = new Foo
                    {
                        Name = "C",
                        ChildFoo = new Foo
                        {
                            Name = "D"
                        }
                    }
                }
            };

            Assert.AreEqual("D", GetLowestLevelFoo(foo).Name);
        }

        public Foo GetLowestLevelFoo(Foo foo)
        {
            if (foo.ChildFoo != null)
            {
                GetLowestLevelFoo(foo.ChildFoo);
            }
            return foo;
        }
    }
+10  A: 

You only want to return foo when you'r at the lowest level. You were returning it no matter what. If you're not at the lowest level you should return the value returned from your recursive call.

public Foo GetLowestLevelFoo(Foo foo)
    {
        if (foo.ChildFoo != null)
        {
            return GetLowestLevelFoo(foo.ChildFoo);
        }
        else
        {
            return foo;
        }
    }
smoore
Bah. I'm sure I tried that. Thank you!
IainMH
+1  A: 

you need to assign foo with the result of your call to GetLowestLevelFoo.

foo = GetLowestLevelFoo(foo.ChildFoo)

otherwise you are returning what you started with.

Nate Heinrich
+2  A: 

edited:

public Foo GetLowestLevelFoo(Foo foo)
{
    if (foo.ChildFoo != null)
    {
        return GetLowestLevelFoo(foo.ChildFoo);
    }
    return foo;
}
Bryan Rowe
You need to return something within the IF as well.
smoore
my bad. quick typing during the mad-dash to supply an answer.
Bryan Rowe
I understand. It's ruthless trying to answer questions out here.
smoore
You don't *need* an else.In fact to remove a level of indentation I would suggest NOT having the else.If the if statement is not satisfied it will skip it and go straight to the return statement - the same as falling into an else block.
Michael Shimmins
A: 

As other have now commented, your code recurses back through the stack, returning each "level of "foo" : finally returning the topmost "node."

Try this :

public Foo GetLowestLevelFoo(Foo foo)
{
    if (foo.ChildFoo == null) return foo;

    return GetLowestLevelFoo(foo.ChildFoo);
}
BillW
@David B You are absolutely right. I will edit my response. I actually single-stepped through the OP's code and watched it return 'foo in four flavours, as it "crawled" back up the stack, before posting my response, so "double shame" on me :) Thanks !
BillW