正确使用try/catch块中的finally子句

sam*_*mis 0 c# exception try-catch

我试图找出在我的sql数据访问层方法中执行(关闭)语句的"最佳"方式.

我想知道这两种方式中的哪一种更正确(谢谢):

选项1

public void dbOperation( ... )
{
    try
    {
        _cmd.Open();        
        _cmd.Execute();
    }
    catch (Exception ex)
    {
        throw ex;       
    }
    finally
    {
        _cmd.Close()
    }   
}
Run Code Online (Sandbox Code Playgroud)

选项#2

public void dbOperation( ... )
{
    try
    {
        _cmd.Open();        
        _cmd.Execute();
    }
    catch (Exception ex)
    {
        _cmd.Close()    
        throw ex;   
    }

    _cmd.Close();
}
Run Code Online (Sandbox Code Playgroud)

Ser*_*rvy 9

两者都不正确.你不应该只有一个catch子句来重新抛出异常,清除它的堆栈跟踪,并且什么都不做,这是你的第一个选择.

你应该被关在最后:

try
{
    _cmd.Open();        
    _cmd.Execute();
}
finally
{
    _cmd.Close()
} 
Run Code Online (Sandbox Code Playgroud)

你的第二个片段也有同样的问题,因为你不正确地重新抛出异常.

最好的选择是使用a using,这只是try/finally的语法糖而没有catch:

using(var command = ...)
{
    command.Open();        
    command.Execute();
}
Run Code Online (Sandbox Code Playgroud)

这还有一个额外的好处,即确保命令的范围与使用它的有效时完全相同.try/finally块要求命令在被处理后成为有效的标识符.

  • @SamusArin它会立即返回,但它会用错误的StackTrace替换Exception的StackTrace成员,声称错误发生在您重新抛出它而不是实际发生的位置."[要保留原始堆栈跟踪信息的异常,请使用throw语句而不指定异常.](http://msdn.microsoft.com/en-us/library/ms182363.aspx)"(请参阅​​示例代码at底部).但正如塞尔维所说,没有理由重新投掷. (2认同)