Share via


Ausnahmebehandlung

Anhand der folgenden Richtlinien können Sie sicherstellen, dass die Bibliothek Ausnahmen angemessen behandelt.

Behandeln Sie Fehler nicht durch das Abfangen von unspezifischen Ausnahmen, zum Beispiel System.Exception, System.SystemException usw., in Frameworkcode.

Sie können Ausnahmen abfangen, wenn die Ausnahme durch das Abfangen erneut ausgelöst oder an einen anderen Thread übertragen werden soll. Im folgenden Codebeispiel wird eine falsche Ausnahmebehandlung veranschaulicht.

Public Class BadExceptionHandlingExample1

    Public Sub DoWork()
        ' Do some work that might throw exceptions.
    End Sub

    Public Sub MethodWithBadHandler()
        Try
            DoWork()
        Catch e As Exception
            ' Handle the exception and 
            ' continue executing.
        End Try
    End Sub
End Class
public class BadExceptionHandlingExample1
{
    public void DoWork()
    {
        // Do some work that might throw exceptions.
    }
    public void MethodWithBadHandler()
    {
        try
        {
            DoWork();
        }
        catch (Exception e)
        {
            // Handle the exception and
            // continue executing.
        }
    }
}
public ref class BadExceptionHandlingExample1
{
public:
    void DoWork()
    {
        // Do some work that might throw exceptions.
    }

    void MethodWithBadHandler()
    {
        try
        {
            DoWork();
        }
        catch (Exception^ e)
        {
            // Handle the exception and
            // continue executing.
        }
    }
};

Vermeiden Sie es, Fehler durch das Abfangen von unspezifischen Ausnahmen, zum Beispiel System.Exception, System.SystemException usw., in Anwendungscode zu behandeln. In bestimmten Fällen ist das Behandeln von Fehlern in Anwendungen zulässig, doch diese Fälle sind selten.

Eine Anwendung darf Ausnahmen nicht behandeln, die zu einem unerwarteten oder als Angriffspunkt geeigneten Zustand führen können. Wenn Sie nicht alle möglichen Ursachen einer Ausnahme vorhersehen können und nicht ausschließen können, dass bösartiger Code den resultierenden Anwendungszustand als Angriffspunkt nutzt, sollten Sie das Beenden der Anwendung zulassen, anstatt die Ausnahme zu behandeln.

Schließen Sie keine speziellen Ausnahmen aus, wenn Sie Ausnahmen abfangen, um sie zu übertragen.

Statt in catch-Klauseln Listen spezieller Ausnahmen zu erstellen, fangen Sie nur Ausnahmen ab, die Sie auf zulässige Weise behandeln können. Ausnahmen, die Sie nicht behandeln können, sollten nicht in unspezifischen Ereignishandlern als Sonderfälle behandelt werden. Im folgenden Codebeispiel wird ein falsches Testen auf spezielle Ausnahmen zum erneuten Auslösen der Ausnahmen veranschaulicht.

Public Class BadExceptionHandlingExample2

    Public Sub DoWork()
        ' Do some work that might throw exceptions.
    End Sub

    Public Sub MethodWithBadHandler()
        Try
            DoWork()
        Catch e As Exception
            If TypeOf e Is StackOverflowException Or _
               TypeOf e Is OutOfMemoryException Then
                Throw
            End If
        End Try
    End Sub
End Class
public class BadExceptionHandlingExample2
{
    public void DoWork()
    {
        // Do some work that might throw exceptions.
    }
    public void MethodWithBadHandler()
    {
        try
        {
            DoWork();
        }
        catch (Exception e)
        {
            if (e is StackOverflowException ||
                e is OutOfMemoryException)
                throw;
            // Handle the exception and
            // continue executing.
        }
    }
}
public ref class BadExceptionHandlingExample2
{
public:
    void DoWork()
    {
        // Do some work that might throw exceptions.
    }

    void MethodWithBadHandler()
    {
        try
        {
            DoWork();
        }
        catch (Exception^ e)
        {
            if (e->GetType() == StackOverflowException::typeid ||
                e->GetType() == OutOfMemoryException::typeid)
                throw;
            // Handle the exception and
            // continue executing.
        }
    }
};

Fangen Sie spezielle Ausnahmen ab, wenn Sie wissen, warum sie in einem bestimmten Kontext ausgelöst werden.

Fangen Sie nur Ausnahmen ab, die behoben werden können. Beispielsweise kann eine FileNotFoundException, die durch den Versuch ausgelöst wird, eine nicht vorhandene Datei zu öffnen, von einer Anwendung behandelt werden, da sie den Benutzer über das Problem informieren und zulassen kann, dass der Benutzer einen anderen Dateinamen angibt oder die Datei erstellt. Eine Anforderung zum Öffnen einer Datei, die eine ExecutionEngineException generiert, sollte nicht behandelt werden, da die Ursache der Ausnahme nicht mit einer gewissen Wahrscheinlichkeit erkannt und die Sicherheit einer weiteren Ausführung durch die Anwendung nicht gewährleistet werden kann.

Fangen Sie Ausnahmen nicht zu häufig ab. Ausnahmen sollten häufig in der Aufrufliste weitergegeben werden können.

Durch das Abfangen von Ausnahmen, die Sie nicht auf zulässige Weise behandeln können, gehen wichtige Debuginformationen verloren.

Verwenden Sie für Bereinigungscode try-finally und nicht try-catch. In gut geschriebenem Ausnahmecode ist try-finally weitaus üblicher als try-catch.

Eine catch-Klausel soll Ihnen das Behandeln von Ausnahmen ermöglichen (z. B. durch Protokollieren eines nicht schwerwiegenden Fehlers). Eine finally-Klausel soll Ihnen die Ausführung von Bereinigungscode ermöglichen, unabhängig davon, ob eine Ausnahme ausgelöst wurde. Wenn Sie aufwendige oder begrenzte Ressourcen, z. B. Datenbankverbindungen oder Streams, reservieren, fügen Sie den Code zu ihrer Freigabe in einen finally-Block ein.

Verwenden Sie eine leere Ausnahme, wenn Sie eine Ausnahme abfangen und erneut auslösen. Dies ist die beste Möglichkeit, die Ausnahmeaufrufliste beizubehalten.

Im folgenden Codebeispiel wird eine Methode veranschaulicht, die eine Ausnahme auslösen kann. Auf diese Methode wird in späteren Beispielen verwiesen.

Public Sub DoWork(ByVal anObject As Object)
    ' Do some work that might throw exceptions.
    If (anObject = Nothing) Then
        Throw New ArgumentNullException("anObject", "Specify a non-null argument.")
    End If
    ' Do work with o.
End Sub
public void DoWork(Object anObject)
{
    // Do some work that might throw exceptions.
    if (anObject == null)
    {
        throw new ArgumentNullException("anObject",
            "Specify a non-null argument.");
    }
    // Do work with o.
}
public:

    void DoWork(Object^ anObject)
    {
        // Do some work that might throw exceptions.
        if (anObject == nullptr)
        {
            throw gcnew ArgumentNullException("anObject",
                "Specify a non-null argument.");
        }
        // Do work with o.
    }

Im folgenden Codebeispiel wird das Abfangen einer Ausnahme und die fehlerhafte Angabe der Ausnahme beim erneuten Auslösen der Ausnahme veranschaulicht. Hierdurch zeigt die Aufrufliste statt auf die DoWork-Methode auf die erneut ausgelöste Ausnahme als Fehlerposition.

        Public Sub MethodWithBadCatch(ByVal anObject As Object)
            Try
                DoWork(anObject)

            Catch e As ArgumentNullException
                System.Diagnostics.Debug.Write(e.Message)
                ' This is wrong.
                Throw e
                ' Should be this:
                ' throw
            End Try
        End Sub

public void MethodWithBadCatch(Object anObject)
{
    try
    {
        DoWork(anObject);
    }
    catch (ArgumentNullException e)
    {
       System.Diagnostics.Debug.Write(e.Message);
       // This is wrong.
       throw e;
       // Should be this:
       // throw;
    }
}
void MethodWithBadCatch(Object^ anObject)
{
    try
    {
        DoWork(anObject);
    }
    catch (ArgumentNullException^ e)
    {
       System::Diagnostics::Debug::Write(e->Message);
       // This is wrong.
       throw e;
       // Should be this:
       // throw;
    }
}

Behandeln Sie nicht CLS-kompatible Ausnahmen (Ausnahmen, die nicht von System.Exception abgeleitet werden) nicht mit einem parameterlosen Catch-Block. Sprachen, die nicht von Exception abgeleitete Ausnahmen unterstützen, können Ausnahmen behandeln, die nicht CLS-kompatibel sind.

.NET Framework, Version 2.0, umschließt nicht-CLS-kompatible Ausnahmen mit einer Klasse, die von Exception abgeleitet wird.

Copyright für einzelne Teile 2005 Microsoft Corporation. Alle Rechte vorbehalten.

Copyright für einzelne Teile Addison-Wesley Corporation. Alle Rechte vorbehalten.

Weitere Informationen zu Entwurfsrichtlinien finden Sie unter „Framework-Entwurfs-Richtlinien: Idiome, Konventionen und Muster für wiederverwendbare .NET-Bibliotheken von Krzysztof Cwalina“ book und Brad Abrams, veröffentlicht von Addison-Wesley, 2005.

Siehe auch

Weitere Ressourcen

Entwurfsrichtlinien zum Entwickeln von Klassenbibliotheken

Entwurfsrichtlinien für Ausnahmen