这是空的try catch块的情况吗?

时间:2012-04-06 20:42:11

标签: c# exception-handling

让我们假设你读了一个大的XML文件,大约25%的节点是可选的,所以你真的不在乎它们是否在那里,但是,如果它们是提供给你的,你仍然会在并对它们做一些事情(例如将它们存储在数据库中)。

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

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

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

3 个答案:

答案 0 :(得分:5)

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

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

而不是:

try
{
  do work with X
}
catch{}

现在如果没有办法确定节点X是否存在而不是尝试使用它,或者如果在检查它是否存在之后可以删除节点X,那么你将被迫使用尝试/捕捉模型。这不是这里的情况。 (相反,在阅读之前检查文件是否存在;有人可以在检查文件是否存在后将其删除。)

<强> -------------------------------------------- ----------------

修改

因为看起来您的问题是在以下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
}

答案 1 :(得分:2)

一般情况下,场景听起来像是使用空catch块的边界线可接受的情况(当然,假设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)) {
  ..
}

答案 2 :(得分:1)

  

由于它们是可选的,因此在这种情况下将它们包装起来是不行的   空尝试捕获块,所以即使他们不在那里,   程序只是继续执行。

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