Die anderen Antworten sind völlig korrekt, aber diese Antwort enthält 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("Ihr Stack-Trace:");
Console.WriteLine(e.StackTrace);
Console.WriteLine();
if (e.InnerException == null) {
Console.WriteLine("Keine innere Ausnahme.");
} else {
Console.WriteLine("Stack-Trace Ihrer inneren Ausnahme:");
Console.WriteLine(e.InnerException.StackTrace);
}
}
}
static void ThrowTest() {
decimal a = 1m;
decimal b = 0m;
try {
Mult(a, b); // Zeile 34
Div(a, b); // Zeile 35
Mult(b, a); // Zeile 36
Div(b, a); // Zeile 37
} catch (ArithmeticException arithExc) {
Console.WriteLine("Behandlung einer {0}.", arithExc.GetType().Name);
// entweder auskommentieren
//throw arithExc;
// oder
//throw;
// oder
//throw new Exception("Wir haben Ihre Ausnahme behandelt und verpackt", 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 Zeile throw arithExc;
auskommentieren, lautet Ihre Ausgabe wie folgt:
Behandlung einer DivideByZeroException.
Ihr Stack-Trace:
bei Program.ThrowTest() in c:\somepath\Program.cs: Zeile 44
bei Program.Main() in c:\somepath\Program.cs: Zeile 9
Keine innere Ausnahme.
Sie haben sicherlich Informationen darüber verloren, wo genau diese Ausnahme aufgetreten ist. Wenn Sie stattdessen die Zeile throw;
verwenden, erhalten Sie folgendes:
Behandlung einer DivideByZeroException.
Ihr Stack-Trace:
bei System.Decimal.FCallDivide(Decimal& d1, Decimal& d2)
bei System.Decimal.Divide(Decimal d1, Decimal d2)
bei Program.Div(Decimal x, Decimal y) in c:\somepath\Program.cs: Zeile 58
bei Program.ThrowTest() in c:\somepath\Program.cs: Zeile 46
bei Program.Main() in c:\somepath\Program.cs: Zeile 9
Keine innere Ausnahme.
Dies ist wesentlich besser, denn jetzt sehen Sie, dass es die Methode Program.Div
war, die Probleme verursacht hat. Es ist jedoch immer noch schwer zu erkennen, ob dieses Problem von Zeile 35 oder Zeile 37 im try
-Block kommt.
Wenn Sie die dritte Alternative verwenden und in eine äußere Ausnahme verpacken, verlieren Sie keine Informationen:
Behandlung einer DivideByZeroException.
Ihr Stack-Trace:
bei Program.ThrowTest() in c:\somepath\Program.cs: Zeile 48
bei Program.Main() in c:\somepath\Program.cs: Zeile 9
Stack-Trace Ihrer inneren Ausnahme:
bei System.Decimal.FCallDivide(Decimal& d1, Decimal& d2)
bei System.Decimal.Divide(Decimal d1, Decimal d2)
bei Program.Div(Decimal x, Decimal y) in c:\somepath\Program.cs: Zeile 58
bei Program.ThrowTest() in c:\somepath\Program.cs: Zeile 35
Insbesondere können Sie sehen, dass es Zeile 35 ist, die zu dem Problem führt. Dies erfordert jedoch, dass die Leute die InnerException
durchsuchen, und es fühlt sich etwas indirekt an, innere Ausnahmen in einfachen Fällen zu verwenden.
In diesem Blog-Beitrag erhalten sie die Zeilennummer (Zeile des try
-Blocks), indem sie (über Reflektion) die internal
Instanzmethode InternalPreserveStackTrace()
auf dem Exception
-Objekt aufrufen. Aber es ist nicht schön, so Reflektion zu verwenden (das .NET-Framework könnte seine internal
-Member eines Tages ohne Vorwarnung ändern).
5 Stimmen
Es gibt einen Unterschied, der damit zu tun hat, ob oder wie der Stapelrückverfolgungsverlauf in der Ausnahme erscheint, aber ich erinnere mich nicht daran, welcher jetzt welcher ist, also werde ich dies nicht als Antwort auflisten.
0 Stimmen
@Joel: Danke. Ich glaube, die Verwendung der HandleError-Ausnahme ist keine gute Idee. Ich wollte nur etwas Fehlerbehandlungscode umstrukturieren.
1 Stimmen
Der dritte Weg besteht darin, eine neue Ausnahme zu umschließen und erneut zu werfen timwise.blogspot.co.uk/2014/05/…
0 Stimmen
Möglicher Duplikat von Unterschied zwischen throw und throw new Exception()
0 Stimmen
Sehen Sie sich dieses YouTube-Video an throw vs throw ex youtube.com/watch?v=WGwOd6yMja4 Wenn Sie Dinge sehen, wird es klarer.