这样做更好吗:
try
{
...
}
catch (Exception ex)
{
...
throw;
}
或:
try
{
...
}
catch (Exception ex)
{
...
throw ex;
}
他们做同样的事情吗?一个比另一个好吗?
这样做更好吗:
try
{
...
}
catch (Exception ex)
{
...
throw;
}
或:
try
{
...
}
catch (Exception ex)
{
...
throw ex;
}
他们做同样的事情吗?一个比另一个好吗?
当前回答
如果抛出一个没有变量的异常(第一个例子),堆栈跟踪将包括抛出异常的原始方法。
在第二个示例中,堆栈跟踪将被更改以反映当前方法。
例子:
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
}
其他回答
第一个保存异常的原始堆栈跟踪,第二个用当前位置替换它。
因此,到目前为止,第一个是更好的。
我发现,如果在捕获异常的同一方法中抛出异常,堆栈跟踪就不会被保留。
void testExceptionHandling()
{
try
{
throw new ArithmeticException("illegal expression");
}
catch (Exception ex)
{
throw;
}
finally
{
System.Diagnostics.Debug.WriteLine("finally called.");
}
}
你应该总是使用"throw;"来重新抛出。net中的异常,
请参考博客文章《甩和甩前男友》。
基本上,MSIL (CIL)有两个指令——“throw”和“rethrow”,c#的“throw ex;”被编译成MSIL的“throw”和c#的“throw;”-进入MSIL“重扔”!基本上,我可以看到为什么“throw ex”覆盖堆栈跟踪的原因。
第一个比较好。如果尝试调试第二个异常并查看调用堆栈,则无法看到原始异常来自何处。如果真的需要重新抛出,有一些技巧可以保持调用堆栈的完整性(尝试搜索,它之前已经被回答过了)。
视情况而定。在调试构建中,我希望尽可能少地查看原始堆栈跟踪。在这种情况下,“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”的一个不太可能的特例。