可能重复:
在 C# 中重新引发异常的正确方法是什么?
我想了解为什么“throw ex”用法会隐藏原始堆栈跟踪?在设计 c# 编译器时,幕后的基本理念是什么?
这实际上不是 C# 问题,而是 CLI 设计问题,归结为不同的 IL 指令throw
和rethrow
.
基本上,throw ex;
(对于任何ex
,甚至是原始的)是一个 IL throw
,其中 -throw;
是一个 IL rethrow
。
如果您要指定要抛出的特定异常,则该异常逻辑上源自此处,现在,此方法。如果不是这种情况,那么:
throw;
而不是throw ex;
, or:将异常包装在另一个异常中,这样您就可以保留原始异常并显示新异常的来源:
throw new SomeException(ex);
在这种情况下,调用者可以通过ex.InnerException
.
当你捕捉到一个异常时,它的“出生地”在其他地方,异常在堆栈跟踪中被带到它被抛出的地方。将其视为throw
初始化Exception
类实例的堆栈跟踪。所以用当前堆栈throw ex;
初始化堆栈跟踪。ex