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

1voto

Tim Sparkles Punkte 739

Um auf die Antwort von Lucero ausführlicher einzugehen, hier ist, wie Sie die Absicht des Originalcodes erreichen können, ohne den ursprünglichen Stack-Trace zu verlieren.

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

    /// 
    ///   true, wenn die Ausnahme behandelt wurde;
    ///   false, wenn die Ausnahme weitergeleitet werden soll
    /// 
    private static bool HandleException(Exception ex) {
        if (ex is ThreadAbortException) {
            // dann ignorieren
            return true;
        }
        if (ex is ArgumentOutOfRangeException) { 
            // dann protokollieren
            return false;
        }
        if (ex is InvalidOperationException) {
            // dann Meldung anzeigen
            return false;
        }
        // und so weiter.
    }
}

0voto

Charles Owen Punkte 1867

Um Ihnen eine andere Perspektive darauf zu geben, ist die Verwendung von throw besonders nützlich, wenn Sie einem Client eine API zur Verfügung stellen möchten und ausführliche Stapelverfolgungsinformationen für Ihre interne Bibliothek bereitstellen möchten. Wenn ich hier throw benutze, erhalte ich in diesem Fall die Stapelverfolgung der System.IO.File-Bibliothek für File.Delete. Wenn ich throw ex benutze, werden diese Informationen nicht an meinen Handler übergeben.

static void Main(string[] args) {            
   Method1();            
}

static void Method1() {
    try {
        Method2();
    } catch (Exception ex) {
        Console.WriteLine("Ausnahme in Method1");             
    }
}

static void Method2() {
    try {
        Method3();
    } catch (Exception ex) {
        Console.WriteLine("Ausnahme in Method2");
        Console.WriteLine(ex.TargetSite);
        Console.WriteLine(ex.StackTrace);
        Console.WriteLine(ex.GetType().ToString());
    }
}

static void Method3() {
    Method4();
}

static void Method4() {
    try {
        System.IO.File.Delete("");
    } catch (Exception ex) {
        // Zeigt den gesamten Stapeltrace in die .NET-
        // oder benutzerdefinierte Bibliothek zu Method2(), wo die Ausnahme behandelt wird
        // Wenn Sie in der Lage sein möchten, den ausführlichsten Stapeltrace zu erhalten
        // in die internen Bestandteile der aufgerufenen Bibliothek
        throw;                
        // throw ex;
        // Zeigt den Stapeltrace von Method4() zu Method2(), wo die Ausnahme behandelt wird
    }
}

-2voto

Bhanu pratap Punkte 73
int a = 0;
try {
    int x = 4;
    int y ;
    try {
        y = x / a;
    } catch (Exception e) {
        Console.WriteLine("inner ex");
        //throw;   // Line 1
        //throw e;   // Line 2
        //throw new Exception("devide by 0");  // Line 3
    }
} catch (Exception ex) {
    Console.WriteLine(ex);
    throw ex;
}
  1. if all Line 1 ,2 and 3 are commented - Output - inner ex

  2. if all Line 2 and 3 are commented - Output - inner ex System.DevideByZeroException: {"Attempted to divide by zero."}---------

  3. if all Line 1 and 2 are commented - Output - inner ex System.Exception: devide by 0 ----

  4. if all Line 1 and 3 are commented - Output - inner ex System.DevideByZeroException: {"Attempted to divide by zero."}---------

and StackTrace will be reset in case of throw ex;

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