有一些帖子问这两者之间已经有什么区别了。(为什么我要提这个…)
但我的问题在某种程度上是不同的,我在另一种错误处理方法中调用了“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有相同的效果?
微软文档代表:
Once an exception is thrown, part of the information it carries is the stack trace. The stack trace is a list of the method call hierarchy that starts with the method that throws the exception and ends with the method that catches the exception. If an exception is re-thrown by specifying the exception in the throw statement, the stack trace is restarted at the current method and the list of method calls between the original method that threw the exception and the current method is lost. To keep the original stack trace information with the exception, use the throw statement without specifying the exception.
来源:https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2200
(我之前发过,@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 ?