这样做更好吗:

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

或:

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

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


当前回答

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

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

其他回答

我发现,如果在捕获异常的同一方法中抛出异常,堆栈跟踪就不会被保留。

void testExceptionHandling()
{
    try
    {
        throw new ArithmeticException("illegal expression");
    }
    catch (Exception ex)
    {
        throw;
    }
    finally
    {
        System.Diagnostics.Debug.WriteLine("finally called.");
    }
}

视情况而定。在调试构建中,我希望尽可能少地查看原始堆栈跟踪。在这种情况下,“throw;”符合要求。

然而,在发布版本中,(a)我想记录包含原始堆栈跟踪的错误,一旦完成,(b)重新设计错误处理以使用户更有意义。这里“抛出异常”是有意义的。重新抛出错误确实会丢弃原始的堆栈跟踪,但非开发人员从查看堆栈跟踪信息中得不到任何信息,因此可以重新抛出错误。

        void TrySuspectMethod()
        {
            try
            {
                SuspectMethod();
            }
#if DEBUG
            catch
            {
                //Don't log error, let developer see
                //original stack trace easily
                throw;
#else
            catch (Exception ex)
            {
                //Log error for developers and then
                //throw a error with a user-oriented message
                throw new Exception(String.Format
                    ("Dear user, sorry but: {0}", ex.Message));
#endif
            }
        }

问题的措辞,让"Throw:"和。“Throw ex;”让它有点转移注意力。真正的选择是在“Throw;”和“Throw Exception”之间,其中“Throw ex;”是“Throw Exception”的一个不太可能的特例。

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

我的偏好是使用

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

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

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

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