这样做更好吗:

try
{
    ...
}
catch (Exception ex)
{
    ...
    throw;
}

或:

try
{
    ...
}
catch (Exception ex)
{
    ...
    throw ex;
}

他们做同样的事情吗?一个比另一个好吗?


当前回答

您应该始终使用以下语法来重新抛出异常。否则你将停止堆栈跟踪:

throw;

如果打印由throw ex产生的跟踪,您将看到它结束于该语句,而不是异常的真正来源。

基本上,使用抛掷前女友应该被视为刑事犯罪。


如果需要重新抛出来自其他地方(AggregateException, TargetInvocationException)或另一个线程的异常,也不应该直接重新抛出。而是使用ExceptionDispatchInfo保存所有必要的信息。

try
{
    methodInfo.Invoke(...);
}
catch (System.Reflection.TargetInvocationException e)
{
    System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(e.InnerException).Throw();
    throw; // just to inform the compiler that the flow never leaves the block
}

其他回答

您应该始终使用以下语法来重新抛出异常。否则你将停止堆栈跟踪:

throw;

如果打印由throw ex产生的跟踪,您将看到它结束于该语句,而不是异常的真正来源。

基本上,使用抛掷前女友应该被视为刑事犯罪。


如果需要重新抛出来自其他地方(AggregateException, TargetInvocationException)或另一个线程的异常,也不应该直接重新抛出。而是使用ExceptionDispatchInfo保存所有必要的信息。

try
{
    methodInfo.Invoke(...);
}
catch (System.Reflection.TargetInvocationException e)
{
    System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(e.InnerException).Throw();
    throw; // just to inform the compiler that the flow never leaves the block
}

第一个保存异常的原始堆栈跟踪,第二个用当前位置替换它。

因此,到目前为止,第一个是更好的。

你应该总是使用"throw;"来重新抛出。net中的异常,

请参考博客文章《甩和甩前男友》。

基本上,MSIL (CIL)有两个指令——“throw”和“rethrow”,c#的“throw ex;”被编译成MSIL的“throw”和c#的“throw;”-进入MSIL“重扔”!基本上,我可以看到为什么“throw ex”覆盖堆栈跟踪的原因。

第一个比较好。如果尝试调试第二个异常并查看调用堆栈,则无法看到原始异常来自何处。如果真的需要重新抛出,有一些技巧可以保持调用堆栈的完整性(尝试搜索,它之前已经被回答过了)。

我的偏好是使用

try
{
}
catch (Exception ex)
{
     ...
     throw new Exception ("Add more context here", ex)
}

这保留了原来的错误,但是它允许您添加更多的上下文,例如对象ID、连接字符串等等。我的异常报告工具通常有五个链接的异常要报告,每个报告更详细。