3

假设您读入一个大型 XML 文件并且大约 25% 的节点是可选的,所以您真的不在乎它们是否存在,但是,如果它们被提供给您,您仍然会读入它们并做一些事情与他们一起(例如将它们存储在数据库中)。

由于它们是可选的,在这种情况下是否可以将它们包装在空try . . . catch块中,所以如果它们不存在,程序只是继续执行?你不关心抛出错误或类似的东西。

请记住,仅仅因为它们是可选的并不意味着您不想检查它们。它只是意味着向您提供 XML 的人或者不希望您知道某些信息,或者他们确实希望您知道并且由您来处理它。

最后,如果这只是几个节点,那没什么大不了的,但是如果您有 100 个可选节点,例如,检查每个节点是否是第一个节点或如果找到nulla 则停止执行可能会很痛苦null,因此我问这是否是空的 try catch 语句的正当理由。

4

3 回答 3

5

如果处理节点 X 是可选的,那么您的代码应类似于:

if(node X exists in file)
{
  do work with X
}

并不是:

try
{
  do work with X
}
catch{}

现在,如果除了尝试使用节点 X 之外无法确定节点 X 是否存在,或者如果在检查节点 X 是否存在后可以将其删除,那么您将被迫使用 try/catch模型。这不是这里的情况。(与说,在读取文件之前检查文件是否存在相反;有人可以在您检查文件是否存在后将其删除。)

-------------------------------------------------- ----------

编辑:

由于您的问题似乎是在以下 XML 中单独访问节点“孙子”,其中“父”可能不存在。(请原谅我在 SO 中呈现此 XML 的能力很差;知识渊博的读者可以随意以适当的格式进行编辑。)

<root>
  <Parent>
    <Child>
      <GrandChild>
        The data I really want.
      </GrandChild>
    </Child>
  </Parent>
</root>

为此,我会做这样的事情:

public static class XMLHelpers
{
public static Node GetChild(this Node parent, string tagName)
{
  if(parent == null) return null;
  return parent.GetNodeByTagName(tagName);
}
}

然后你可以这样做:

var grandbaby = rootNode.GetChild("Parent").GetChild("Child").GetChild("GrandChild");
if(grandbaby != null)
{
  //use grandbaby
}
于 2012-04-06T20:46:32.800 回答
2

一般来说,这种情况听起来像是使用空 catch 块的边界可接受的情况(当然假设 catch 的范围是没有节点时抛出的异常的类型)。由于如果节点不存在,您没有任何工作要做,因此代码执行将按计划继续。

我确实质疑null在这里检查的痛苦是否太大。检查 null 的代码量/痛苦是 2 行

if (parent.IsPresente("child")) {
  var child = parent.GetNode("child");
}

虽然的开销try / catch同样冗长

try { 
  DoSomething(parent.GetNode("child"));
} catch (TheExceptionType) { }

鉴于这种选择,我会选择这种if方法。它同样具有声明性,一般来说更快,整体上更好的风格。异常实际上应该只用于异常情况。事前无法预防的事情。这是一种非常可预防的情况,甚至可以通过扩展方法来支持该模式,使其更可口

XmlNode child;
if (parent.TryGetNode("child", out child)) {
  ..
}
于 2012-04-06T20:47:59.243 回答
1

由于它们是可选的,在这种情况下是否可以将它们包装在空的 try catch 块中,所以即使它们不存在,程序也会继续执行。

否 - 相反,您应该在执行任何其他操作之前检查特定节点是否存在。由于您希望有时会出现这种情况,因此您的程序逻辑应该涵盖这一点,这不是异常处理的用例。

于 2012-04-06T20:45:29.087 回答