c# - 这些 try/catch 是等价的吗?

标签 c# .net exception exception-handling

场景

我有一个执行数据库操作的方法(比方说)。如果在该操作期间引发任何异常,我只想将该异常抛给调用者。我不想在 catch block 中执行任何特定任务,假设调用者会对该异常做任何它想做的事情。在这种情况下,哪种异常处理技术是合适的?

try
{
    // Some work that may generate exception
}
catch(Exception)
{
    throw;
}
finally
{
    // Some final work
}

上面的是否等同于下面的try/catch/finally?

try
{
    // Some work that may generate exception
}
catch
{
    throw;
}
finally
{
    // Some final work
}

上面的是否等同于下面的try/finally?

try
{
    // Some work that may generate exception
}
finally
{
    // Some final work
}

哪个比另一个好?应该使用哪一个?

最佳答案

不,它们不等价。它们可能在某些情况下是等效的,但一般答案是否定的。

不同类型的catch block

catch 具有指定异常类型的 block

以下只会捕获继承自 System.Exception 的托管异常,然后执行 finally block ,无论是否抛出异常都会发生。

try
{
   // Some work that may generate exception
}
catch (Exception)
{
   throw;
}
finally
{
   // Some final work
}

catch 没有指定异常类型的 block

下面没有类型说明符的 catch block 也将捕获不一定由托管 System.Exception 对象表示的非托管异常,然后执行 finally block ,无论是否抛出异常都会发生。

try
{
   // Some work that may generate exception
}
catch
{
   throw;
}
finally
{
   // Some final work
}

finally block 没有 catch block

如果你根本没有 catch block ,无论是否发生异常,你的 finally 仍然会被执行。

try
{
   // Some work that may generate exception
}
finally
{
  // Some final work
}

它们什么时候等价?

如果您的 catch block 没有指定异常并且只包含 throw; 语句,最后两个确实是等价的。如果您不关心非托管异常并且您的 catch block 仅包含 throw; 语句,那么这三个都可以被认为是等价的。

注意事项

关于throw的注释

以下两段代码有细微差别。后者将重新抛出异常,这意味着它将重写异常的堆栈跟踪,因此这些绝对是等效的:

catch (Exception e)
{
    throw;
}

catch (Exception e)
{
    throw e;
}

如果您将 finallyIDisposable 一起使用,则以下两段代码几乎相同,但有一些细微差别:

  • 当对象为 null 时,using 语句不会给您一个 NullReferenceException
  • 当使用try-finally 技术时,变量保留在范围内,尽管非常不鼓励使用任何对象在它被处置之后。但是,您仍然可以将变量重新分配给其他东西。

    东西 obj = null; 尝试 { obj = 新东西() //做一点事 } 最后 { obj.Dispose();

using (var obj = new Something())
{
    // Do something
}

关于c# - 这些 try/catch 是等价的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41873242/

相关文章:

.net - 将依赖项合并到控制台应用程序中

c# - 使用 ninject 作为 WPF View 模式定位器 - View 模型作为单例

c# - AccountManagement创建用户返回 'object already exists'异常

c# - 从 F# 调用 C# 函数

c# - GDI+ 就像在 WPF 中绘图一样

c# - 忽略特定类型的异常

c# - 使用 LINQ 比较 C# 中的两个列表并将缺失项添加到实体类的最简单方法

c# - 使用 Reactive Extensions、嵌套订阅按组缓冲

C++ "Proper"异常处理方式

c# - 加载相关对象时出现异常。 Entity Framework