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

λ J*_*kas 3 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);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

Kar*_*rim 13

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

也许这样做:

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

return false
Run Code Online (Sandbox Code Playgroud)

  • 代码检查器不知道......你是理解算法的功劳.它只能理解代码路径(其中一条路径被Karim指出). (3认同)

Jhe*_*ico 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 第1步和第2步很好,但第3步被破坏,因为代码将始终根据第一个子节点的子节点返回true或false,而不是*all*孙子节点.如果您的第二个孩子的第一个孩子是目标节点,您的代码仍将返回false.此外,*我*没有说早期的回报是邪恶的.我说有些人可能会说.我一直是编码指南禁止它们的地方.我不知道我头脑中的理由. (2认同)