Die anderen Antworten sind völlig richtig, aber diese Antwort bietet meiner Meinung nach einige zusätzliche Details.
Betrachten Sie dieses Beispiel:
using System;
static class Program {
static void Main() {
try {
ThrowTest();
} catch (Exception e) {
Console.WriteLine("Your stack trace:");
Console.WriteLine(e.StackTrace);
Console.WriteLine();
if (e.InnerException == null) {
Console.WriteLine("No inner exception.");
} else {
Console.WriteLine("Stack trace of your inner exception:");
Console.WriteLine(e.InnerException.StackTrace);
}
}
}
static void ThrowTest() {
decimal a = 1m;
decimal b = 0m;
try {
Mult(a, b); // line 34
Div(a, b); // line 35
Mult(b, a); // line 36
Div(b, a); // line 37
} catch (ArithmeticException arithExc) {
Console.WriteLine("Handling a {0}.", arithExc.GetType().Name);
// uncomment EITHER
//throw arithExc;
// OR
//throw;
// OR
//throw new Exception("We handled and wrapped your exception", arithExc);
}
}
static void Mult(decimal x, decimal y) {
decimal.Multiply(x, y);
}
static void Div(decimal x, decimal y) {
decimal.Divide(x, y);
}
}
Wenn Sie die throw arithExc;
Zeile auskommentieren , lautet Ihre Ausgabe:
Handling a DivideByZeroException.
Your stack trace:
at Program.ThrowTest() in c:\somepath\Program.cs:line 44
at Program.Main() in c:\somepath\Program.cs:line 9
No inner exception.
Sicherlich haben Sie Informationen darüber verloren, wo diese Ausnahme aufgetreten ist. Wenn Sie stattdessen die throw;
Leitung verwenden, erhalten Sie Folgendes:
Handling a DivideByZeroException.
Your stack trace:
at System.Decimal.FCallDivide(Decimal& d1, Decimal& d2)
at System.Decimal.Divide(Decimal d1, Decimal d2)
at Program.Div(Decimal x, Decimal y) in c:\somepath\Program.cs:line 58
at Program.ThrowTest() in c:\somepath\Program.cs:line 46
at Program.Main() in c:\somepath\Program.cs:line 9
No inner exception.
Das ist viel besser, denn jetzt sehen Sie, dass es die Program.Div
Methode war, die Ihnen Probleme verursacht hat. Es ist jedoch immer noch schwer zu erkennen, ob dieses Problem von Zeile 35 oder Zeile 37 im try
Block herrührt.
Wenn Sie die dritte Alternative verwenden, eine äußere Ausnahme einschließen, verlieren Sie keine Informationen:
Handling a DivideByZeroException.
Your stack trace:
at Program.ThrowTest() in c:\somepath\Program.cs:line 48
at Program.Main() in c:\somepath\Program.cs:line 9
Stack trace of your inner exception:
at System.Decimal.FCallDivide(Decimal& d1, Decimal& d2)
at System.Decimal.Divide(Decimal d1, Decimal d2)
at Program.Div(Decimal x, Decimal y) in c:\somepath\Program.cs:line 58
at Program.ThrowTest() in c:\somepath\Program.cs:line 35
Insbesondere können Sie sehen, dass es Zeile 35 ist , die zum Problem führt. Dies erfordert jedoch, dass die Leute das suchen InnerException
, und es fühlt sich etwas indirekt an, in einfachen Fällen innere Ausnahmen zu verwenden.
In diesem Blog-Beitraginternal
behalten sie die Zeilennummer (Zeile des try-Blocks) bei, indem sie (durch Reflexion) die Intance-Methode InternalPreserveStackTrace()
für das Exception
Objekt aufrufen . Es ist jedoch nicht schön, eine solche Reflexion zu verwenden (.NET Framework könnte internal
eines Tages seine Mitglieder ohne Vorwarnung ändern ).