.net 为什么异常的行号指向Throw语句?
假设我有以下构造:.net 为什么异常的行号指向Throw语句?,.net,vb.net,.net,Vb.net,假设我有以下构造: Try Dim f As FileInfo = Nothing f.Delete() ... some other stuff... Catch ex as Exception Throw End Try 在这个简单的示例中,f.Delete将抛出NullReferenceException 为什么此异常的StackTrace中的问题行指向Throw语句,而不是f.Delete()行 如何保持Try/Catch,但将正确的堆栈跟踪指向f.Delete(
Try
Dim f As FileInfo = Nothing
f.Delete()
... some other stuff...
Catch ex as Exception
Throw
End Try
在这个简单的示例中,f.Delete
将抛出NullReferenceException
Throw
语句,而不是f.Delete()
行f.Delete()
作为问题的根源抛出生成的堆栈跟踪,还是由捕获的第一个异常生成的堆栈跟踪
在Catch ex As Exception
行上设置断点,并使用调试器检查ex
;您将看到一个指向f.Delete()
的堆栈跟踪
Throw
表示“重新抛出”,即原始堆栈跟踪将被保留但是,对于同一方法调用,堆栈跟踪中不会有两个条目:如果在最初导致异常的同一方法中重新抛出异常,堆栈跟踪将只包含一个指向最终重新抛出的条目。
二,。如何保持Try/Catch,但使正确的堆栈跟踪指向f.Delete()作为问题的根源
请记住,重新抛出基本上意味着“我错了,我不知道如何处理这个异常。”因此,您可以使用异常过滤器(Catch…When
)来决定是否能够在捕获异常之前处理它。如果您可以在捕获它之前确定,那么应该不需要重新调用,并且不会修改堆栈跟踪
将f.Delete()
放在不同的方法中。这样,它在堆栈跟踪中获得自己的堆栈帧/行,并且不会被重新抛出的
覆盖
(或者,不要捕获异常只是为了重新显示它。)我想这也可以用来给出正确的异常(至少在“内部”异常中):
我认为您所解释的行为是使用throw ex发生的情况。这就是为什么我们使用throw
来推测正确的行为。我认为throw
和throw-ex
之间的区别在于throw
将保持原来抛出的堆栈跟踪,而throw-ex
将显示从执行堆栈跟踪的行开始的堆栈跟踪。@Denis:我已经重写了我的答案。现在应该更有帮助了。所以我在做了一些测试之后现在明白了。无论您是使用抛出
还是抛出ex
,这里的结果都是一样的。这两种方法都将以相同的方式覆盖此方法的堆栈帧。@Denis:在您的具体情况中可能没有区别。(另请参见和。)然而,我仍然认为原则上,Throw
和Throw ex
的含义/意图不同。如果您决定无法处理异常,因此希望(尽可能)保留原始堆栈跟踪,请执行重新抛出。执行一个Throw ex
在“新”抛出位置有一个异常点。不要重新抛出异常在VB.NET中很多人在方法中捕捉到异常(不管这是好的还是坏的做法)因为他们喜欢做运行时调试,如果抛出异常,它会留在函数/子函数中。他们通常通过上面的构造实现这一点,但当异常发生在代码深处时,它会导致问题,我无法确定涉及哪一行。简而言之,他们希望保留这个结构,但要使它正常工作。如果您只需要一个Try..Catch
块,您可以始终使用标志来确定错误发生的位置。例如,在f.Delete()
之后将整数设置为1表示成功。然后在您的Catch
中,您可以测试整数,以查看您的代码是否通过了f.Delete()
Try
Dim f As FileInfo = Nothing
f.Delete()
... some other stuff...
Catch ex as Exception
Throw New Exception("Failed in Method X", ex)
End Try