560 Stimmen

Gibt es einen Unterschied zwischen "throw" und "throw ex"?

Es gibt bereits einige Beiträge, die nach dem Unterschied zwischen den beiden fragen.
(Warum muss ich das überhaupt erwähnen...)

Aber meine Frage unterscheidet sich insofern, als dass ich "throw ex" in einer anderen Fehler gottgleichen Behandlungsmethode aufrufe.

public class Program {
    public static void Main(string[] args) {
        try {
            // etwas
        } catch (Exception ex) {
            HandleException(ex);
        }
    }

    private static void HandleException(Exception ex) {
        if (ex is ThreadAbortException) {
            // dann ignorieren,
            return;
        }
        if (ex is ArgumentOutOfRangeException) { 
            // dann protokollieren,
            throw ex;
        }
        if (ex is InvalidOperationException) {
            // dann Nachricht anzeigen,
            throw ex;
        }
        // und so weiter.
    }
}

Wenn try & catch im Main verwendet wurden, würde ich throw; verwenden, um den Fehler erneut zu werfen. Aber im obigen vereinfachten Code durchlaufen alle Ausnahmen HandleException.

Hat throw ex; den gleichen Effekt wie das Aufrufen von throw, wenn es innerhalb von HandleException aufgerufen wird?

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/…

9voto

Mahesh Punkte 81

Lass uns den Unterschied zwischen throw und throw 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 unabhängig davon, wo die Ausnahme tatsächlich ausgelöst wurde, den Stapelablauf der Ausnahme neu.

Lass uns das anhand eines Beispiels verstehen.

Lassen Sie uns zuerst Throw verstehen.

static void Main(string[] args) {
    try {
        M1();
    } catch (Exception ex) {
        Console.WriteLine(" ----------------- Stapelablauf-Hierarchie -----------------");
        Console.WriteLine(ex.StackTrace.ToString());
        Console.WriteLine(" ---------------- Methodenname / Zielseite -------------- ");
        Console.WriteLine(ex.TargetSite.ToString());
    }
    Console.ReadKey();
}

static void M1() {
    try {
        M2();
    } catch (Exception ex) {
        throw;
    };
}

static void M2() {
    throw new DivideByZeroException();
}

Die Ausgabe des obigen Codes ist unten aufgeführt.

Zeigt die vollständige Hierarchie und den Methodennamen, an dem die Ausnahme tatsächlich aufgetreten ist. Es handelt sich um M2 -> M2, einschließlich Zeilennummern.

Bildbeschreibung eingeben

Zweitens.. lass uns durch throw ex verstehen. Ersetzen Sie einfach throw durch throw ex im catch-Block von Methode M2. wie unten.

Bildbeschreibung eingeben

Die Ausgabe des throw ex Codes ist wie folgt.

Bildbeschreibung eingeben

Sie können den Unterschied in der Ausgabe sehen.. throw ex ignoriert einfach die gesamte vorherige Hierarchie und setzt den Stapelablauf mit der Zeile/Methode zurück, an der throw ex geschrieben ist.

7voto

Arman Sahakyan Punkte 163

Microsoft Docs steht für:

Sobald eine Ausnahme ausgelöst wird, enthält sie auch Informationen zum Stack-Trace. Der Stack-Trace ist eine Liste der Methoden-Aufrufhierarchie, die mit der Methode beginnt, die die Ausnahme auslöst, und mit der Methode endet, die die Ausnahme abfängt. Wenn eine Ausnahme durch Angabe der Ausnahme im throw-Anweisung erneut ausgelöst wird, wird der Stack-Trace an der aktuellen Methode neu gestartet und die Liste der Methodenaufrufe zwischen der ursprünglichen Methode, die die Ausnahme ausgelöst hat, und der aktuellen Methode geht verloren. Um die ursprünglichen Stack-Trace-Informationen beizubehalten, verwenden Sie die throw-Anweisung ohne Angabe der Ausnahme.

Quelle: https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2200

6voto

Lucero Punkte 57715

Nein, dies wird dazu führen, dass die Ausnahme einen anderen Stapelspeicher hat. Nur die Verwendung eines throw ohne jedes Ausnahmeobjekt im catch-Handler belässt den Stapelspeicher unverändert.

Sie möchten vielleicht ein boolesches Ergebnis von HandleException zurückgeben, ob die Ausnahme erneut geworfen werden soll oder nicht.

3voto

Aaaaaaaa Punkte 1865

Schau hier: http://blog-mstechnology.blogspot.de/2010/06/throw-vs-throw-ex.html

Throw:

try 
{
    // Führe eine Operation aus, die fehlschlagen kann
}
catch (Exception ex)
{
    // Führe lokale Bereinigung durch
    throw;
}

Es bewahrt die Stapelinformationen mit Ausnahme

Dies wird als "Weiterwerfen" bezeichnet

Wenn Sie eine neue Ausnahme auslösen möchten,

throw new ApplicationException("Vorgang fehlgeschlagen!");

Throw Ex:

try
{
    // Führe eine Operation aus, die fehlschlagen kann
}
catch (Exception ex)
{
    // Führe lokale Bereinigung durch
    throw ex;
}

Es sendet keine Stapelinformationen mit Ausnahme

Dies wird als "Stapelspeicherung unterbrechen" bezeichnet

Wenn Sie eine neue Ausnahme auslösen möchten,

throw new ApplicationException("Vorgang fehlgeschlagen!",ex);

3voto

Maksud Punkte 147

Es ist besser, throw anstelle von throw ex zu verwenden.

throw ex setzt den ursprünglichen Stack-Trace zurück und der vorherige Stack-Trace kann nicht gefunden werden.

Wenn wir throw verwenden, erhalten wir einen vollständigen Stack-Trace.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X