这样做更好吗:
try
{
...
}
catch (Exception ex)
{
...
throw;
}
或:
try
{
...
}
catch (Exception ex)
{
...
throw ex;
}
他们做同样的事情吗?一个比另一个好吗?
这样做更好吗:
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.");
}
}
其他回答
我的偏好是使用
try
{
}
catch (Exception ex)
{
...
throw new Exception ("Add more context here", ex)
}
这保留了原来的错误,但是它允许您添加更多的上下文,例如对象ID、连接字符串等等。我的异常报告工具通常有五个链接的异常要报告,每个报告更详细。
我发现,如果在捕获异常的同一方法中抛出异常,堆栈跟踪就不会被保留。
void testExceptionHandling()
{
try
{
throw new ArithmeticException("illegal expression");
}
catch (Exception ex)
{
throw;
}
finally
{
System.Diagnostics.Debug.WriteLine("finally called.");
}
}
您应该始终使用以下语法来重新抛出异常。否则你将停止堆栈跟踪:
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
}
第一个比较好。如果尝试调试第二个异常并查看调用堆栈,则无法看到原始异常来自何处。如果真的需要重新抛出,有一些技巧可以保持调用堆栈的完整性(尝试搜索,它之前已经被回答过了)。
如果抛出一个没有变量的异常(第一个例子),堆栈跟踪将包括抛出异常的原始方法。
在第二个示例中,堆栈跟踪将被更改以反映当前方法。
例子:
static string ReadAFile(string fileName) {
string result = string.Empty;
try {
result = File.ReadAllLines(fileName);
} catch(Exception ex) {
throw; // This will show ReadAllLines in the stack trace
throw ex; // This will show ReadAFile in the stack trace
}