VB.NET Try/Catch/When-远离还是有它的用途?

VB.NET Try/Catch/When-远离还是有它的用途?,vb.net,exception-handling,Vb.net,Exception Handling,与c#不同,VB.NET有一个特性,可以有条件地捕获Try/catch/Finally块中的异常 我想我在某个地方读到过,这通常是一种不好的做法,因为它鼓励人们将(业务)逻辑放在异常处理机制中,而实际上,您最终得到的是一个美化的GoTo Try // Do something Catch ex As MyException When [condition] // End Try 那么,当使用功能时,是否有合法的情况可以使用,或者我们应该远离它? 这可能已经得到了回答,但我

与c#不同,VB.NET有一个特性,可以有条件地捕获Try/catch/Finally块中的异常

我想我在某个地方读到过,这通常是一种不好的做法,因为它鼓励人们将(业务)逻辑放在异常处理机制中,而实际上,您最终得到的是一个美化的
GoTo

Try
     // Do something
Catch ex As MyException When [condition]
     // 
End Try
那么,当使用
功能时,是否有合法的情况可以使用
,或者我们应该远离它?


这可能已经得到了回答,但我找不到任何相关信息,因为“When”对于搜索来说是一个非常糟糕的关键字。

我能想到的通常情况是,当您只想根据该异常的内容捕获特定异常时。例如:

Try
     // Do something
Catch ex As SqlException When ex.Number = 547
     // Constraint Violation
End Try
这样可以避免捕获所有的,然后检查
Number
属性,如果不匹配,则必须重新抛出异常

另见:

例如,如果您有一个相当普遍的异常,比如COMException,那么您通常只希望在它表示某个HRESULT时捕获它。例如,当它表示E_失败时,您希望让它不受伤害,但当它表示E_访问被拒绝时,您希望捕获它,因为您有一个替代方案。这里,这是一个完全合理的条件捕获条款:

另一种方法是将条件放置在catch块中,如果异常不符合您的条件,则重新抛出异常。例如:

从逻辑上讲,这个“catch/rethrow”模式与过滤器做的事情是一样的,但有一个微妙而重要的区别。如果异常未经处理,则两者的程序状态完全不同。在catch/rethrow情况下,未处理的异常似乎来自catch块中的Throw语句。除此之外,将不会有任何调用堆栈,直到catch子句的任何finally块都将被执行。两者都使调试更加困难。在filter情况下,异常从原始抛出点开始未经处理,finally子句未更改任何程序状态


也许值得编辑一下,指出异常过滤器现在在C#now中可用(与问题中的第一句相反)fwiw。。。我的理解是,所有其他的事情(捕捉原作、检查数字、重新投掷)仍然在发生。只是现在您维护的代码不必直接处理它。@JoelCoehoorn-异常过滤器内置于CLRs异常处理机制中。VB(和C#now)编译器并不是真的在插入这段代码。异常过滤器实际上比任何手动处理都更早启动(例如,它们实际上在任何内部
最终
条款生效之前启动)
Catch ex As System.Runtime.InteropServices.COMException When ex.ErrorCode() = &H80070005 
Catch ex As System.Runtime.InteropServices.COMException 
    If (ex.ErrorCode != &H80070005) Then Throw