这是否适用于空的try catch块?

3
假设您读取了一个大型的XML文件,其中约25%的节点是可选的,因此如果它们存在,您仍将读取并处理它们(例如将它们存储在数据库中),但如果它们不存在,那么您也不会过多关心。既然这些节点是可选的,那么把它们放在空的try ... catch块中就可以了,这样如果它们不存在,程序就会继续执行。您并不关心是否会出现错误或类似的情况。
请注意,即使这些节点是可选的,您仍然需要检查它们是否存在。这只是意味着提供XML的人要么不想让您知道某些信息,要么他们确实希望您知道,并由您来处理。
最后,请注意,如果只有几个节点是可选的,那么问题并不大。但是,如果您有100个可选节点,例如,那么检查每个节点是否为null或在找到null时停止执行可能很麻烦,因此我问了一下是否可以使用空的try catch语句。

6
不要使用异常来控制程序流程。加上空指针检查。 - cadrell0
@cadrell0 - 这是我的一个观点,如果有几个空值检查,那还好,但如果你有上百个呢。 - Xaisoft
1
或者制定一种更加智能、通用的处理方式。通常可以通过为每种数据类型(例如扩展)创建一个方法来解决这个问题(该方法将在“存在性”之上检查格式),以进行特定的检查/加载,然后在内部适当地放置if语句(或类似的语句,具体取决于情况、具体示例和具体解决方案),总有办法解决。 - NSGaga-mostly-inactive
1
如果一个空值检查比一个空的try-catch块更有效率,那么成百上千个空值检查比成百上千个try-catch块更有效率。 - phoog
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中的“grandchild”节点,而父级节点“Parent”可能不存在。(请原谅我的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
}

2

通常情况下,如果catch的范围仅限于没有节点时抛出异常的类型,则使用空catch块是可以接受的边缘情况。因为如果节点不存在,你不需要进行任何工作,代码将按计划继续执行。

我质疑在此处检查null的痛苦是否太过强烈。检查null所需的代码/痛苦量为2行。

if (parent.IsPresente("child")) {
  var child = parent.GetNode("child");
}
< p >使用 try/catch 时,开销同样冗长。
try { 
  DoSomething(parent.GetNode("child"));
} catch (TheExceptionType) { }

如果要选择的话,我会选择 if 方法。它同样具有声明性、通常更快且整体风格更好。异常应该只在特殊情况下使用。而这种情况是可以预防的。通过扩展方法支持该模式,甚至可以使其更易接受。

XmlNode child;
if (parent.TryGetNode("child", out child)) {
  ..
}

是的,程序的执行不依赖于节点。当我说痛苦时,我指的是可能有数百个嵌套节点,这将导致一个巨大的嵌套if语句。 - Xaisoft
@Xaisoft 我们需要了解更多关于程序的信息才能尝试进行任何概括,但例如在JaredPar的代码中,即使传入null,使DoSomething正确工作可以将空检查移动到一个辅助方法中,而不是100个调用它。 - Servy
@Xaisoft,你考虑过使用XPath查询来处理深层嵌套吗? - JaredPar
@JaredPar - 没有,你能提供一个小例子吗?因为我对xpath不是很熟悉。 - Xaisoft
@Xaisoft,请查看我回答的编辑,它解决了您在这些评论中提出的问题。 - Servy
显示剩余2条评论

1
既然它们是可选的,那么在这种情况下将它们包装在空的 try catch 块中,以便在不存在时程序继续执行是否可以呢? 不可以 - 相反,在执行任何其他操作之前,应该检查特定节点是否存在。由于您有时希望出现这种情况,因此您的程序逻辑应涵盖此问题,这不是异常处理的用例。

这是一个修辞问题,但是嵌套节点怎么办,比如说有10个或更多的嵌套节点,那不会导致一个大的if null、if null、if null...语句吗? - Xaisoft
@Xaisoft 不是很难。你只需要将if检查嵌套在彼此内部。if(have(A)){if(have(B)){use A+B}}(请在不使用SO评论时使用换行符)。 - Servy
@Servy - 你说得对,我想这只是一开始的痛苦,对吧? - Xaisoft

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接