如何正确使用try-catch语句

本文关键字:try-catch 语句 何正确 | 更新日期: 2023-09-27 18:03:04

距离上次编程练习已经有一段时间了,所以这里有一个相当基本的问题。然而,我还没有找到任何具体的答案。

假设我定义了一个可能导致异常的方法。该方法看起来像这样(用伪代码):

public int Calculate(int x, int y) 
{
  try 
  {
    doSomeCalc();
  }
  catch (SomeException ex) 
  {
    doExceptionHandling();
  }
  return result;
}

现在如果应用程序的另一部分想要使用这个方法,它应该使用另一个try-catch块吗?

public MyMainApp() {
  try 
  {
    Calculate(1, 2);
  } 
  catch (SomeException ex) 
  {
    doExceptionHandling();
  }
}

所以这里的问题是我应该在哪里使用try-catch,哪里是多余的?

如何正确使用try-catch语句

一般来说,只有在catch中可以执行某些操作时,才应该使用try-catch。是否可以重试失败的连接或帮助用户继续?是否要记录异常?

如果您无法恢复或优雅地降级,那么捕获异常就没有意义。只要让它冒泡到应用程序顶部的catch(例如,在web应用程序基页的Page_Error事件中),并在那里处理UI。

一般来说,当需要处理某些语句执行引起的错误时,应该使用try-catch。

例如,在Db连接的情况下,会抛出SqlException,它可以包含与错误相关的信息,如Wrong Password, Invalid Database

try
{
    //try connect to db
}
catch (SqlException ex)
{
    // information of database related exception
}
catch (Exception ex)
{
    // catch any other error
}

Exception Handling有时并不像看起来那么简单。

请阅读这篇文章(我个人从中学到了很多):.NET中的异常处理最佳实践

如果Calculate已经捕获异常并处理它,为什么MyMainApp要关心它呢?如果它没有捕获它,MyMainApp可能想要处理它。如果它没有以一种有用的方式处理它,它应该不捕获它(至少记录异常)。

最佳实践是尽快抛出有意义的异常,例如(假设负值可能导致错误的结果或异常):

public int Calculate(int x, int y)
{
    if (x <= 0)
        throw new ArgumentException("X has to be positive", "x");
    if (y <= 0)
        throw new ArgumentException("Y has to be positive", "y");
    // now the calculation should be safe without any side-effects
    // ...
}

这取决于SomeException类型。如果它是所有异常的基类,则不需要在第二个块中使用它。但是,如果它只处理一种特定类型的异常,并且可能发生其他类型的异常,则需要第二个块。为什么只需要处理一个特定的异常?如果需要的话,你可以自己找出答案:)

经验法则是,您只捕获将要处理异常的地方。例如,记录一个特定的异常或重新尝试调用。

为了保持堆栈跟踪,通常使用throw;重新抛出异常,然后在进程的顶部设置一些机制来全局处理错误。

尝试将Try和catch放入event functions中,因为普通函数只能从事件函数中调用。只有在其他层函数中使用try,如果要执行一些rollbacks。希望对大家有所帮助....