如何在不重置堆栈跟踪的情况下抛出exception?

这是一个后续问题, “throw”和“throw ex”之间有区别吗?

有没有办法提取新的error handling方法而不重置堆栈跟踪?

[编辑]我将尝试“内部方法”和Earwicker提供的另一个答案 ,看看哪个可以更好地标记答案。

不确定你的意思是,但我在你的另一个问题中的建议是解决这个问题。

如果你的处理程序返回一个布尔值,无论是否处理了exception,你可以在catch子句中使用它:

catch (Exception ex) { if (!HandleException(ex)) { throw; } } 

是; 这就是InnerException属性的用途。

 catch(Exception ex) { throw new YourExceptionClass("message", ex); } 

这将允许您添加自己的逻辑,然后抛出自己的exception类。 YourExceptionClass实例的StackTrace将来自此代码块,但InnerException将是您捕获的exception,使用之前的StackTrace。

使用.NET Framework 4.5,现在有一个ExceptionDispatchInfo支持这种确切的场景。 它允许捕获完整的exception并从其他地方重新抛出它而不会覆盖包含的堆栈跟踪。

由于评论请求而导致的代码示例

 using System.Runtime.ExceptionServices; class Test { private ExceptionDispatchInfo _exInfo; public void DeleteNoThrow(string path) { try { File.Delete(path); } catch(IOException ex) { // Capture exception (including stack trace) for later rethrow. _exInfo = ExceptionDispatchInfo.Capture(ex); } } public Exception GetFailure() { // You can access the captured exception without rethrowing. return _exInfo != null ? _exInfo.SourceException : null; } public void ThrowIfFailed() { // This will rethrow the exception including the stack trace of the // original DeleteNoThrow call. _exInfo.Throw(); // Contrast with 'throw GetFailure()' which rethrows the exception but // overwrites the stack trace to the current caller of ThrowIfFailed. } } 

您不希望使用原始堆栈跟踪创建新exception。 这是误导,因为堆栈跟踪没有创建新的exception。

但是,您可以将原始exception作为“InnerException”放在新exception中。 这会做你想要的吗?

您是否正在捕捉您想要过滤的exception,然后您可以改变主意,决定不处理它们并重新抛出它们?

如果你想对此非常小心,那不是一个好主意。 最好永远不要抓住exception。 原因是给定的try/catch处理程序不应该决定为不期望看到的exception运行嵌套的finally块。 例如,如果存在NullReferenceException ,则继续执行任何代码可能是一个非常糟糕的主意,因为它可能会导致抛出另一个此类exception。 finally块就像代码一样,就像任何其他代码一样。 一旦第一次捕获到exception, try/catch下面的堆栈上的任何finally块都将被执行,到时为止已经太晚了 – 可能会生成另一个exception,这意味着原始exception将丢失。

这意味着(在C​​#中)你必须小心地为你想要捕获的所有exception类型写出一个单独的catch处理程序。 它还意味着您只能按例外类型进行过滤。 这有时是非常难以遵循的建议。

应该可以通过其他方式过滤exception,但在C#中则不是。 但是,它可以在VB.NET中使用,并且BCL本身通过使用VB.NET编写的少量代码来利用这一点,因此它可以以更方便的方式过滤exception。

以下是来自CLR团队博客的VB.NET代码示例的详细说明。

这是我的两分钱。