548 Stimmen

Was ist der richtige Weg, um eine Ausnahme in C# erneut auszulösen?

Ist es besser, dies zu tun:

try
{
    ...
}
catch (Exception ex)
{
    ...
    throw;
}

Oder dies:

try
{
    ...
}
catch (Exception ex)
{
    ...
    throw ex;
}

Erfüllen sie dieselbe Aufgabe? Ist das eine besser als das andere?

10voto

Vinod T. Patil Punkte 2881

Sie sollten immer "throw;" verwenden, um die Ausnahmen in .NET erneut zu werfen,

Siehe den Blogbeitrag Wurf vs. Wurf ex .

Grundsätzlich hat MSIL (CIL) zwei Anweisungen - "throw" und "rethrow" - und C#s "throw ex;" wird in MSILs "throw" und C#s "throw;" kompiliert - in MSIL "rethrow"! Im Grunde kann ich den Grund dafür sehen, warum "throw ex" den Stack-Trace außer Kraft setzt.

5voto

Mendelt Punkte 35649

Die erste ist besser. Wenn Sie versuchen, die zweite zu debuggen und sich den Aufrufstapel ansehen, werden Sie nicht sehen, woher die ursprüngliche Ausnahme kam. Es gibt Tricks, um den Aufrufstapel intakt zu halten (versuchen Sie die Suche, es wurde bereits beantwortet), wenn Sie wirklich brauchen, um rethrow.

3voto

James Punkte 12410

Ich habe festgestellt, dass der Stack-Trace nicht erhalten bleibt, wenn die Ausnahme in der gleichen Methode ausgelöst wird, in der sie auch abgefangen wird.

void testExceptionHandling()
{
    try
    {
        throw new ArithmeticException("illegal expression");
    }
    catch (Exception ex)
    {
        throw;
    }
    finally
    {
        System.Diagnostics.Debug.WriteLine("finally called.");
    }
}

2voto

Perry Tribolet Punkte 2498

Das kommt darauf an. Bei einem Debug-Build möchte ich den ursprünglichen Stack-Trace mit so wenig Aufwand wie möglich sehen. In diesem Fall ist "throw;" die richtige Wahl.

In einem Release-Build möchte ich jedoch (a) den Fehler mit dem ursprünglichen Stack-Trace protokollieren und dann (b) die Fehlerbehandlung so umgestalten, dass sie für den Benutzer mehr Sinn ergibt. Hier macht "Throw Exception" Sinn. Es stimmt zwar, dass beim erneuten Auslösen des Fehlers der ursprüngliche Stacktrace verworfen wird, aber ein Nicht-Entwickler hat nichts davon, wenn er die Stacktrace-Informationen sieht, also ist es in Ordnung, den Fehler erneut auszulösen.

        void TrySuspectMethod()
        {
            try
            {
                SuspectMethod();
            }
#if DEBUG
            catch
            {
                //Don't log error, let developer see
                //original stack trace easily
                throw;
#else
            catch (Exception ex)
            {
                //Log error for developers and then
                //throw a error with a user-oriented message
                throw new Exception(String.Format
                    ("Dear user, sorry but: {0}", ex.Message));
#endif
            }
        }

Die Art und Weise, wie die Frage formuliert ist und "Throw:" gegen "Throw ex;" ausspielt, macht sie zu einem Ablenkungsmanöver. Die wirkliche Wahl ist zwischen "Throw;" und "Throw Exception", wobei "Throw ex;" ein unwahrscheinlicher Spezialfall von "Throw Exception" ist.

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