C# 这是空try-catch块的情况吗?

C# 这是空try-catch块的情况吗?,c#,exception-handling,C#,Exception Handling,假设您读入了一个大的XML文件,大约25%的节点是可选的,因此您确实不在乎它们是否存在,但是,如果它们提供给您,您仍然会读入它们并对它们进行处理(例如,将它们存储在db中) 因为它们是可选的,所以在这种情况下用空的try来包装它们不是很好吗。catch块,因此如果它们不在那里,程序会继续执行吗?你不在乎抛出一个错误或任何类似的东西 请记住,仅仅因为它们是可选的并不意味着您不想检查它们。这只是意味着,提供XML的人要么不想让您知道某些信息,要么他们确实想让您知道,由您来处理这些信息 最后,如果这只

假设您读入了一个大的XML文件,大约25%的节点是可选的,因此您确实不在乎它们是否存在,但是,如果它们提供给您,您仍然会读入它们并对它们进行处理(例如,将它们存储在db中)

因为它们是可选的,所以在这种情况下用空的
try来包装它们不是很好吗。catch
块,因此如果它们不在那里,程序会继续执行吗?你不在乎抛出一个错误或任何类似的东西

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

最后,如果这只是几个节点,那也没什么大不了的,但是如果你有100个节点是可选的,比如说,首先检查每个节点是否为
null
,或者如果发现
null
则停止执行,这可能是一个痛苦的过程,因此我问这是否是try-catch语句为空的有效原因

既然它们是可选的,那么在这种情况下,将它们包装起来不是很好吗 清空try catch块,使其在中,即使它们不在那里 程序只是继续执行


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

如果处理节点X是可选的,那么您的代码应该如下所示:

if(node X exists in file)
{
  do work with X
}
而不是:

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

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

编辑:

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

然后你可以做:

var grandbaby = rootNode.GetChild("Parent").GetChild("Child").GetChild("GrandChild");
if(grandbaby != null)
{
  //use grandbaby
}

通常情况下,对于使用空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)) {
  ..
}

不要将异常用于流控制。把空检查放进去。@cadrell0-这是我的观点之一,如果有一些空检查,这很好,但是如果你有100个…或者用一种更智能、更通用的处理方式呢。通常这很容易解决,例如,每种类型的数据都有一个方法(例如扩展)(在“存在”的基础上检查两种格式),具体检查/加载-然后在内部可以正确放置if(或沿着这些线,取决于具体情况、具体示例和具体解决方案),总是有办法的。@Xaisoft如果一个null检查比一个空的try-catch块更有效,那么数百个null检查比数百个try-catch块更有效。这是一个反问句,但是嵌套节点呢,比如说有10个或更多嵌套节点,这不会导致一个大的if-null,if-null,如果为空。。。。声明。@Xaisoft不是真的。您只需将if检查嵌套在彼此内部
if(have(A)){if(have(B)){use A+B}}
(如果不在SO注释中使用,请使用换行符。)@Servy-你有一点,我想这只是开始时的一个痛苦,对吗?是的,程序的执行不依赖于节点。当我说痛苦时,我的意思是可能有100个嵌套节点,这将导致一个巨大的嵌套if语句。@Xaisoft好的,我想我在这里看到的场景更好一些。你基本上是说,这不是一系列的sybling节点,而是一个深度嵌套的遍历。@Xaisoft我们需要更多地了解程序,以尝试任何形式的泛化,但是,例如,在JaredPar的代码中,即使传入了
null
,DoSomething也能正常工作,这样就可以将null检查移到一个helper方法,而不是对其进行100次调用。@Xaisoft您没有考虑过对深嵌套使用xpath查询吗?@JaredPar-没有,你能提供一个小例子吗?因为我对xpath不太熟悉
try { 
  DoSomething(parent.GetNode("child"));
} catch (TheExceptionType) { }
XmlNode child;
if (parent.TryGetNode("child", out child)) {
  ..
}