有一些帖子问这两者之间已经有什么区别了。(为什么我要提这个…)
但我的问题在某种程度上是不同的,我在另一种错误处理方法中调用了“throw ex”。
public class Program {
public static void Main(string[] args) {
try {
// something
} catch (Exception ex) {
HandleException(ex);
}
}
private static void HandleException(Exception ex) {
if (ex is ThreadAbortException) {
// ignore then,
return;
}
if (ex is ArgumentOutOfRangeException) {
// Log then,
throw ex;
}
if (ex is InvalidOperationException) {
// Show message then,
throw ex;
}
// and so on.
}
}
如果在主线中使用try和catch,那么我会使用throw;重新抛出错误。
但是在上面的简单代码中,所有异常都通过HandleException
是否抛出前任;在HandleException内部调用时,与调用throw有相同的效果?
(我之前发过,@Marc Gravell纠正了我)
以下是其中的区别:
static void Main(string[] args) {
try {
ThrowException1(); // line 19
} catch (Exception x) {
Console.WriteLine("Exception 1:");
Console.WriteLine(x.StackTrace);
}
try {
ThrowException2(); // line 25
} catch (Exception x) {
Console.WriteLine("Exception 2:");
Console.WriteLine(x.StackTrace);
}
}
private static void ThrowException1() {
try {
DivByZero(); // line 34
} catch {
throw; // line 36
}
}
private static void ThrowException2() {
try {
DivByZero(); // line 41
} catch (Exception ex) {
throw ex; // line 43
}
}
private static void DivByZero() {
int x = 0;
int y = 1 / x; // line 49
}
这是输出:
Exception 1:
at UnitTester.Program.DivByZero() in <snip>\Dev\UnitTester\Program.cs:line 49
at UnitTester.Program.ThrowException1() in <snip>\Dev\UnitTester\Program.cs:line 36
at UnitTester.Program.TestExceptions() in <snip>\Dev\UnitTester\Program.cs:line 19
Exception 2:
at UnitTester.Program.ThrowException2() in <snip>\Dev\UnitTester\Program.cs:line 43
at UnitTester.Program.TestExceptions() in <snip>\Dev\UnitTester\Program.cs:line 25
您可以看到,在例外1中,堆栈跟踪返回到DivByZero()方法,而在例外2中则没有。
但是请注意,在ThrowException1()和ThrowException2()中显示的行号是throw语句的行号,而不是调用DivByZero()的行号,现在我稍微思考一下,这可能是有意义的……
释放模式输出
例外1:
at ConsoleAppBasics.Program.ThrowException1()
at ConsoleAppBasics.Program.Main(String[] args)
例外2:
at ConsoleAppBasics.Program.ThrowException2()
at ConsoleAppBasics.Program.Main(String[] args)
它是否只在调试模式下维护原始的stackTrace ?
看这里:http://blog-mstechnology.blogspot.de/2010/06/throw-vs-throw-ex.html
把:
try
{
// do some operation that can fail
}
catch (Exception ex)
{
// do some local cleanup
throw;
}
它保留了异常堆栈信息
这叫做"重扔"
如果想要抛出新的异常,
throw new ApplicationException("operation failed!");
把交货:
try
{
// do some operation that can fail
}
catch (Exception ex)
{
// do some local cleanup
throw ex;
}
它不会发送异常堆栈信息
这叫做“打破堆栈”
如果想要抛出新的异常,
throw new ApplicationException("operation failed!",ex);