C#:并非所有代码路径都返回一个值

时间:2009-10-27 23:21:44

标签: c# compilation

我正在编写一个简单的WinForms应用程序,我允许用户在TreeView控件中拖动TreeNodes。我强制执行的规则之一是不允许用户将TreeNode拖动到其自己的子节点之一。我以递归样式编写了以下函数来检查目标节点的父级。编译后,我收到错误 并非所有代码路径都为此函数返回值 。据我所知,我对这个逻辑的每个可能的分支都有一个回复声明......但我显然是错的。有人可以指出我的错误。

    private bool IsDestinationNodeAChildOfDraggingNode(TreeNode draggingNode, TreeNode destinationNode) {
        if (draggingNode.Nodes.Count == 0) 
            return false;
        else {
            if (draggingNode.Nodes.Contains(destinationNode)) 
                return true;
            else {
                foreach (TreeNode node in draggingNode.Nodes) 
                    return IsDestinationNodeAChildOfDraggingNode(node, destinationNode);
            }
        }
    }

7 个答案:

答案 0 :(得分:13)

这可能是指如果draggingNode.Nodes中没有任何项目,那么它将从else中退出并退出函数而不返回任何内容。

也许这样做:

foreach (TreeNode node in draggingNode.Nodes) 
     return IsDestinationNodeAChildOfDraggingNode(node, destinationNode);

return false

答案 1 :(得分:8)

其实我觉得你的算法错了。如果你只是要查看第一个值,为什么还要用foreach语句呢?此外,返回后的所有其他内容都是多余的,使代码更难以遵循。

我怀疑你要做的事情更像是这样:

private bool IsDestinationNodeAChildOfDraggingNode(TreeNode draggingNode, TreeNode destinationNode) {
  // special case, no children
  if (draggingNode.Nodes.Count == 0) 
    return false;

  // check if the target is one of my children
  if (draggingNode.Nodes.Contains(destinationNode)) 
     return true;

  // recursively check each of my children to see if one of their descendants is the target
  foreach (TreeNode node in draggingNode.Nodes) 
    if (IsDestinationNodeAChildOfDraggingNode(node, destinationNode)) 
        return true;

  // didn't find anything
  return false;
}

有些人会坚持认为,早期的回归是邪恶的,这将导致这个版本的功能:

private bool IsDestinationNodeAChildOfDraggingNode(TreeNode draggingNode, TreeNode destinationNode) {
  bool retVal = false;

  if (draggingNode.Nodes.Count != 0) {

    // check if the target is one of my children
    if (draggingNode.Nodes.Contains(destinationNode)) {
      retVal = true;
    } else {

      // recursively check each of my children to see if one of their descendants is the target
      foreach (TreeNode node in draggingNode.Nodes) 
        if (IsDestinationNodeAChildOfDraggingNode(node, destinationNode)) {
          retVal = true;
          break;
        }
    }
  }

  return retVal;
}

答案 2 :(得分:2)

编译器认为您需要在return循环之后添加foreach,因为draggingNode.Nodes中可能没有节点,因此循环实际上不会执行。< / p>

private bool IsDestinationNodeAChildOfDraggingNode(TreeNode draggingNode, TreeNode destinationNode) {
    if (draggingNode.Nodes.Count == 0) 
        return false;
    else {
        if (draggingNode.Nodes.Contains(destinationNode)) 
            return true;
        else {
            foreach (TreeNode node in draggingNode.Nodes) 
            {
                return IsDestinationNodeAChildOfDraggingNode(node, destinationNode);
            }
            return false; // <-- here for example
        }
    }
}

现在这可能不是您的算法的正确位置,但编译器认为此处缺少return。按照Jherico建议的方式重新编写代码将使情况更加清晰。

答案 3 :(得分:1)

如果draggingNodes.Nodes中没有项目怎么办?然后你不会返回一个值。

答案 4 :(得分:0)

我的期望是,如果foreach中的所有元素都无法返回任何内容,或者没有节点,则foreach循环不能保证返回值。在最后的if / else / foreach之后,添加一个默认的返回值。

答案 5 :(得分:0)

我猜测C#编译器假定foreach循环正常终止,而不是返回大约三个控制级别。

答案 6 :(得分:0)

在外面的其他地方你必须返回一些东西。

例如:

private bool IsDestinationNodeAChildOfDraggingNode(TreeNode draggingNode, TreeNode destinationNode) {
if (draggingNode.Nodes.Count == 0) 
        return false;
else {
       if (draggingNode.Nodes.Contains(destinationNode)) 
            return true;
       else {
            foreach (TreeNode node in draggingNode.Nodes) 
            return IsDestinationNodeAChildOfDraggingNode(node, destinationNode);
            }
    }
//Return something here.
}