让我们假设你读了一个大的XML文件,大约25%的节点是可选的,所以你真的不在乎它们是否在那里,但是,如果它们是提供给你的,你仍然会在并对它们做一些事情(例如将它们存储在数据库中)。
因为它们是可选的,所以在这种情况下将它们包装在空的try . . . catch
块中是不行的,所以如果它们不在那里,程序就会继续执行?你不关心抛出错误或类似的东西。
请记住,仅仅因为它们是可选的并不意味着您不想检查它们。它只是意味着向您提供XML的人不希望您知道某些信息,或者他们确实希望您知道,并且由您来处理它。
最后,如果这只是几个节点,那就不是什么大问题了,但是如果你有100个节点是可选的,那么检查每个节点是否null
可能会很痛苦如果找到null
,则首先执行或停止执行,因此我询问这是否是空try try语句的正当理由。
答案 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)
由于它们是可选的,因此在这种情况下将它们包装起来是不行的 空尝试捕获块,所以即使他们不在那里, 程序只是继续执行。
否 - 相反,您应该在执行任何其他操作之前检查特定节点是否存在。由于你有时会期待这种情况,你的程序逻辑应该涵盖这一点,这不是异常处理的用例。