递归.并非所有代码路径都返回值

umb*_*sar 1 c# recursion

我相信我在这里犯了一个愚蠢的错误,但它击败了我.这是一段代码:

void Main()
{
    //Key is a parent while the list contains its children
    Dictionary<string,List<string>> d = new Dictionary<string,List<string>>();
    d.Add("1",new List<string>(){"2","3"});//valid.should return false 
    d.Add("2",new List<string>(){"4"});//valid.should return false
    d.Add("3",new List<string>(){"5"});//valid.should return false
    d.Add("4",new List<string>(){"1"});//invalid.should return true 

   IsChildAlreadyAParent("4","2",d);
 }

private bool IsChildAlreadyAParent( string child, string parent, Dictionary<string, List<string>> d )
{           
    if( !d.ContainsKey( child ) || ( d.ContainsKey( child ) && d[child].Count == 0 ))
    {
        return false;
    }

    foreach( string childOfChild in d[child] )
     {
        if( childOfChild == parent )
            return true;

        if( IsChildAlreadyAParent( childOfChild, parent, d ) ) return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

编译这个给了我这个错误:

IsChildAlreadyAParent(string, string, System.Collections.Generic.Dictionary<string,System.Collections.Generic.List<string>>)':并非所有代码路径都返回值

我已经阅读了几次代码,但我无法看到如何错过返回条件.我知道我可以通过在方法结束之前添加方法return语句来纠正它,但它无助于我理解手头的问题.差距在哪里?

Ben*_*igt 6

您可能认为这只执行一次循环体,总是从函数返回:

foreach( string childOfChild in d[child] )
{
    if( childOfChild == parent )
        return true;

    return IsChildAlreadyAParent( childOfChild, parent, d );
}
Run Code Online (Sandbox Code Playgroud)

但是,如果d[child]没有任何元素呢?

此外,仅测试第一个孩子可能也不是正确的解决方案.

更好:

foreach( string childOfChild in d[child] )
{
    if( childOfChild == parent ) return true;
    if (IsChildAlreadyAParent( childOfChild, parent, d )) return true;
}
return false;
Run Code Online (Sandbox Code Playgroud)

  • @wanderer:对不起,编译器不够聪明,没注意到你已经测试了一个空列表.所以它仍然关注循环下面发生的事情. (2认同)