这个Catch声明有什么意义?

时间:2009-09-22 17:12:09

标签: vb.net error-handling

我在遗留代码中看到了这一点。什么,如果有的话,是在Catch中单次投掷的目的?

       Try
           'Some Oracle access statement
       Catch err As OracleClient.OracleException
            Throw
       Finally
          'Do something
       End Try

结果是否与未捕获原始错误的结果相同?您是否会使用带有参数的Throw语句来重新抛出原始错误,通常是在首先执行某些操作之后?

7 个答案:

答案 0 :(得分:4)

我经常在调试时使用该模式;我将在throw语句中设置断点,以便我可以检查err。不确定是否有另一个很好的理由这样做。

答案 1 :(得分:3)

许多人认为这是一种无操作,但事实并非如此。如果你有这个程序:

Module Module1
    Function Filter() As Boolean
        Console.WriteLine("1")
        Return True
    End Function

    Sub Thrower()
        Try
            Throw New Exception("x")
        Finally
            Console.WriteLine("3")
        End Try
    End Sub

    Sub NoCatch()
        Try
            Thrower()
        Finally
            Console.WriteLine("2")
        End Try
    End Sub

    Sub WithCatch()
        Try
            Thrower()
        Catch ex As Exception
            Throw
        Finally
            Console.WriteLine("2")
        End Try
    End Sub

    Sub Caller(ByVal method As Action)
        Try
            method()
        Catch ex As Exception When Filter()
        End Try
    End Sub

    Sub Main()
        Console.WriteLine("No Catch")
        Caller(AddressOf NoCatch)
        Console.WriteLine("With Catch")
        Caller(AddressOf WithCatch)
    End Sub
End Module

输出

No Catch
1
3
2
With Catch
3
1
2

编辑:这个实际上很重要的一个场景: Thrower和NoCatch函数位于同一个程序集中,该程序集已被强制使用。 Caller方法不受信任和恶意。现在假设Thrower方法使用WindowsIdentity模拟另一个用户,不允许不受信任的程序集执行此操作。然后它依赖于一个使用块(= try / finally)来取消对用户的冒充,但它会引发异常。这意味着恶意程序集在执行Filter方法期间作为模拟用户运行。也许这在断言权限时也会起作用,但我不确定。

答案 2 :(得分:1)

这将重新抛出相同的错误。它允许你在Finally块中完成工作,同时将错误抛给调用者

修改

显然,Exception会在没有捕获的情况下冒泡并重新抛出,因此不需要它。我有所纠正。

答案 3 :(得分:1)

这没有任何作用。抛出正确的。

你可以删除捕获但是如果在Finally中有多个注释,你想要离开试试。

答案 4 :(得分:1)

它捕获错误然后再次抛出它。我没有看到这一点,因为你可以尝试...最后没有Catch子句...

jenningj有一个很好的观点,它本可以用来检查带有断点的错误,但它不应该出现在生产代码中。

答案 5 :(得分:1)

看起来它被用来冒泡错误。虽然在这种情况下通常会在catch语句中放入更多而不仅仅是throw(即日志记录,警报等),但它允许使用finally语句进行一些清理,然后将错误冒泡到下一级别。没有try / catch,如何在此范围内编写此清理代码?正如有人提到的那样,throw语法(没有ex)保留了堆栈跟踪。

答案 6 :(得分:0)

使用不带参数的throw的主要原因是它将保留原始的堆栈跟踪。

另外,在throw语句上放置一个断点,你可以更改你的VS设置以打破oracle异常,这比在整个地方添加断点要容易得多