Es gibt einige Beiträge, in denen gefragt wird, was der Unterschied zwischen diesen beiden bereits ist.
(Warum muss ich das überhaupt erwähnen ...)
Aber meine Frage ist anders in einer Weise , dass ich „throw ex“ nenne in einem anderen Fehler gottähnlichen Verfahren handhaben .
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.
}
}
Wenn try & catch
in der verwendet würde Main
, würde ich verwenden throw;
, um den Fehler erneut zu werfen. Im oben genannten vereinfachten Code werden jedoch alle Ausnahmen durchlaufenHandleException
Hat throw ex;
das den gleichen Effekt wie ein Anruf, throw
wenn er im Inneren angerufen wird HandleException
?
c#
.net
exception
exception-handling
dance2die
quelle
quelle
Antworten:
Ja, es gibt einen Unterschied.
throw ex
setzt den Stack-Trace zurück (sodass Ihre Fehler anscheinend von stammenHandleException
)throw
nicht - der ursprüngliche Täter würde erhalten bleiben.quelle
(Ich habe früher gepostet und @Marc Gravell hat mich korrigiert)
Hier ist eine Demonstration des Unterschieds:
und hier ist die Ausgabe:
Sie können sehen, dass in Ausnahme 1 die Stapelverfolgung auf die
DivByZero()
Methode zurückgeht, in Ausnahme 2 jedoch nicht.Beachten Sie jedoch, dass die in
ThrowException1()
und gezeigteThrowException2()
Zeilennummer die Zeilennummer derthrow
Anweisung ist, nicht die Zeilennummer des AnrufsDivByZero()
, was jetzt wahrscheinlich Sinn macht, da ich ein wenig darüber nachdenke ...Ausgabe im Release-Modus
Ausnahme 1:
Ausnahme 2:
Wird die ursprüngliche stackTrace nur im Debug-Modus beibehalten?
quelle
DevideByZero
, sodass der Stack-Trace derselbe ist. Vielleicht sollten Sie dies als eigene Frage postenDie anderen Antworten sind völlig richtig, aber diese Antwort bietet meiner Meinung nach einige zusätzliche Details.
Betrachten Sie dieses Beispiel:
Wenn Sie die
throw arithExc;
Zeile auskommentieren , lautet Ihre Ausgabe:Sicherlich haben Sie Informationen darüber verloren, wo diese Ausnahme aufgetreten ist. Wenn Sie stattdessen die
throw;
Leitung verwenden, erhalten Sie Folgendes: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 imtry
Block herrührt.Wenn Sie die dritte Alternative verwenden, eine äußere Ausnahme einschließen, verlieren Sie keine Informationen:
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-Beitrag
internal
behalten sie die Zeilennummer (Zeile des try-Blocks) bei, indem sie (durch Reflexion) die Intance-MethodeInternalPreserveStackTrace()
für dasException
Objekt aufrufen . Es ist jedoch nicht schön, eine solche Reflexion zu verwenden (.NET Framework könnteinternal
eines Tages seine Mitglieder ohne Vorwarnung ändern ).quelle
Lassen Sie uns den Unterschied zwischen Wurf und Wurf Ex verstehen. Ich habe gehört, dass in vielen .net-Interviews diese häufig gestellte Frage gestellt wird.
Um einen Überblick über diese beiden Begriffe zu geben, werden sowohl throw als auch throw ex verwendet, um zu verstehen, wo die Ausnahme aufgetreten ist. Throw ex schreibt die Stapelverfolgung der Ausnahme neu, unabhängig davon, wo sie tatsächlich ausgelöst wurde.
Lassen Sie uns mit einem Beispiel verstehen.
Lass uns zuerst Throw verstehen.
Die Ausgabe der oben genannten ist unten.
Zeigt die vollständige Hierarchie und den Methodennamen an, bei denen die Ausnahme tatsächlich ausgelöst wurde. Es ist M2 -> M2. zusammen mit Zeilennummern
Zweitens .. lassen Sie uns durch Wurf ex verstehen. Ersetzen Sie einfach throw durch throw ex im Fangblock der M2-Methode. wie nachstehend.
Die Ausgabe des Wurf-Ex-Codes ist wie folgt.
Sie können den Unterschied in der Ausgabe sehen. Throw ex ignoriert einfach die gesamte vorherige Hierarchie und setzt die Stapelverfolgung mit der Zeile / Methode zurück, in die throw ex geschrieben ist.
quelle
Wenn Sie dies tun
throw ex
, wird diese ausgelöste Ausnahme zur "ursprünglichen". Der gesamte vorherige Stack-Trace ist also nicht vorhanden.Wenn Sie dies tun
throw
, geht die Ausnahme nur die ganze Linie hinunter und Sie erhalten den vollständigen Stack-Trace.quelle
Nein, dies führt dazu, dass die Ausnahme einen anderen Stack-Trace hat. Nur wenn Sie ein
throw
Objekt ohne Ausnahme imcatch
Handler verwenden, bleibt die Stapelverfolgung unverändert.Möglicherweise möchten Sie einen Booleschen Wert von HandleException zurückgeben, unabhängig davon, ob die Ausnahme erneut ausgelöst werden soll oder nicht.
quelle
MSDN steht für :
quelle
Schauen Sie hier: http://blog-mstechnology.blogspot.de/2010/06/throw-vs-throw-ex.html
Werfen :
Die Stapelinformationen bleiben mit Ausnahme erhalten
Dies wird als "Rethrow" bezeichnet.
Wenn Sie eine neue Ausnahme auslösen möchten,
Werfen Sie Ex :
Es werden keine Stapelinformationen mit Ausnahme gesendet
Dies wird als "Breaking the Stack" bezeichnet.
Wenn Sie eine neue Ausnahme auslösen möchten,
quelle
Um Ihnen eine andere Perspektive zu geben, ist die Verwendung von throw besonders nützlich, wenn Sie einem Client eine API bereitstellen und ausführliche Stapelverfolgungsinformationen für Ihre interne Bibliothek bereitstellen möchten. Wenn Sie hier throw verwenden, wird in diesem Fall die Stapelverfolgung der System.IO.File-Bibliothek für File.Delete abgerufen. Wenn ich throw ex verwende, werden diese Informationen nicht an meinen Handler weitergegeben.
quelle
wenn alle Zeilen 1, 2 und 3 kommentiert sind - Ausgabe - innere ex
Wenn alle Zeilen 2 und 3 kommentiert sind - Ausgabe - inner ex System.DevideByZeroException: {"Versuch, durch Null zu teilen."} ---------
wenn alle Zeilen 1 und 2 kommentiert sind - Ausgabe - inner ex System.Ausnahme: durch 0 teilen ----
Wenn alle Zeilen 1 und 3 kommentiert sind - Ausgabe - inner ex System.DevideByZeroException: {"Versuch, durch Null zu teilen."} ---------
und StackTrace werden im Falle eines Wurf-Ex zurückgesetzt;
quelle