起初,我会做类似以下的事情:
public void WriteToFile(string filePath, string contents)
{
try
{
File.WriteAllText(filePath, contents)
}
catch(Exception ex)
{
//Log error
}
}
但后来我决定捕获WriteAllText方法的所有特定异常,如下所示:
public void WriteToFile(string filePath, string contents)
{
try
{
File.WriteAllText(filePath, contents);
}
catch (IOException ex)
{
//An I/O error occured when opening the file
}
catch (ArgumentException ex)
{
//The exception that is thrown when one of the arguments provided to a method
that is not valid.
}
catch (UnauthorizedAccessException ex)
{
//Unauthorized access
}
catch (SecurityException ex)
{
//Security exception
}
catch (NotSupportedException ex)
{
//Invoked method not supported
}
}
以上是非常冗长的,并且使用其他方法,它可能更多。有没有更好的方法来做到这一点,所以我不必编写这么多的catch语句。此外,如果捕获到异常,最好从中返回,请记录它。我总是对如何处理它感到困惑。
我注意到了一些困惑。我将处理异常,我遗漏了处理异常以保持简短。我将使用ex变量。问题更多的是关于做catch(Exception ex)或多个catch语句。
我也提出这个问题,因为我总是在这里处理特定的异常而不是一个全面的例外。如果我误解了这一点,请澄清它的含义。
答案 0 :(得分:2)
这取决于你正在处理异常的 。例如,如果SecurityException将导致您向用户提供对话框以提供其凭据,那么您应该有一个单独的catch子句。如果没有,则无需明确地将它们全部调用。
E.g。
try
{
File.WriteAllText(filePath, contents);
}
catch (SecurityException ex)
{
//present dialog
}
catch (Exception ex)
{
//All other exceptions handled the same
}
答案 1 :(得分:1)
典型地,你的try / catch语句将远离你在问题中显示的调用堆栈。这有两个主要原因。首先,低级方法不知道如何处理在其中发生的异常,因为它没有足够的上下文。如果低级方法(例如保存文档的方法)对其处理异常的情况了解得足够多,那么这就是抽象漏洞的标志。其次是更高级别的程序流程将取决于保存操作是否成功。出于这些原因,所有这些类型的异常最好在最高级别进行,例如在UI层中。
尽管如此,有时会有一长串例外 - 正如你所拥有的那样 - 正是要走的路。如果你需要处理一堆不同的情况,那么它需要一堆不同的catch语句,这就是它的方式。
然而,其中一些例外情况并不需要被捕获。例如,永远不需要捕获ArgumentException。相反,最好每次都传递正确的参数。唯一需要捕获ArgumentException的时候,如果你正在调用一个poory设计的库,你不能事先知道参数是否好。精心设计的图书馆将提供替代方案。
因此,只需明智地检查每种类型的例外情况并确定实际预期会发生哪些事件,就可以缩短捕获语句列表。
答案 2 :(得分:0)
我同意上面的SLaks。如果您不处理它,没有理由捕获特定的例外。如果您可以处理某些异常而不处理其他异常,那么您应该抓住所有异常,至少记录有关异常的重要信息。
答案 3 :(得分:0)
最好的方法在很大程度上取决于应用程序的性质和用户的期望。如果您正在创建一个Word处理应用程序,并且上面的操作是保存用户的文档,那么吞下异常并在不通知用户的情况下进行记录将非常糟糕!在这种情况下,我会抓住具体的例外情况,这样我就可以更好地向用户报告问题所在。
相反,如果您保存的文件不重要,例如对内存中保留的某些数据进行句点缓存,您可能只想记录而不是通知用户。在这种情况下,我会寻找一个通用的catch-all,只记录异常细节。