Freigeben über


Ausnahmebehandlung (C#-Programmierhandbuch)

Aktualisiert: November 2007

Mit einem try-Block können C#-Programmierer Code partitionieren, der möglicherweise von einer Ausnahme betroffen ist, und mit catch-Blöcken werden sich daraus ergebende Ausnahmen behandelt. Ein finally-Block kann verwendet werden, um Code unabhängig davon auszuführen, ob eine Ausnahme ausgelöst wird. Dies ist manchmal erforderlich, da Code hinter einem try/catch-Konstrukt nicht ausgeführt wird, wenn eine Ausnahme ausgelöst wird. try-Blöcke müssen entweder mit einem catch-Block oder mit einem finally-Block verwendet werden und können mehrere catch-Blöcke umfassen. Beispiel:

try
{
    // Code to try here.
}
catch (SomeSpecificException ex)
{
    // Code to handle exception here.
    // Only catch exceptions you know how to handle.
    // Never catch base class System.Exception without
    // rethrowing it at the end of the catch block.
}
try
{
    // Code to try here.
}
finally
{
    // Code to execute after try here.
}
try
{
    // Code to try here.
}
catch (SomeSpecificException ex)
{
    // Code to handle exception here.
}
finally
{
    // Code to execute after try (and possibly catch) here.
}

Eine try-Anweisung ohne einen catch-Block oder einen finally-Block führt zu einem Compilerfehler.

Catch-Blöcke

Ein catch-Block kann einen abzufangenden Ausnahmetyp angeben. Dieser Typ wird als Ausnahmefilter bezeichnet und sollte ein Typ sein, der von Exception abgeleitet wird. Im Allgemeinen geben Sie keine Exception in einem catch-Block an, es sei denn, Sie sind sich sicher, wie alle Ausnahmen bearbeitet werden sollen, die im try-Block ausgelöst werden können, oder wenn Sie keine throw-Anweisung am Ende des catch-Blocks einfügen.

Mehrere catch-Blöcke mit verschiedenen Ausnahmefiltern können miteinander verkettet werden. Mehrere catch-Blöcke werden von oben nach unten ausgewertet, für jede ausgelöste Ausnahme wird aber nur ein catch-Block ausgeführt. Der erste catch-Block, der den exakten Typ oder eine Basisklasse der ausgelösten Ausnahme angibt, wird ausgeführt. Wenn kein catch-Block einen passenden Ausnahmefilter angibt, wird ein catch-Block ohne einen Filter (falls vorhanden) ausgeführt. Es ist wichtig, catch-Blöcke mit den spezifischsten (den am stärksten abgeleiteten) Ausnahmeklassen zuerst zu positionieren.

Sie sollten Ausnahmen abfangen, wenn die folgenden Bedingungen gelten:

  • Sie wissen, warum die Ausnahme ausgelöst wurde, und können eine konkrete Lösung für das Problem implementieren. Sie können z. B. ein FileNotFoundException-Objekt abfangen und den Benutzer auffordern, einen neuen Dateinamen einzugeben.

  • Sie können eine neue und spezifischere Ausnahme erstellen und auslösen. Beispiel:

    int GetInt(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch(System.IndexOutOfRangeException e)
        {
            throw new System.ArgumentOutOfRangeException(
                "Parameter index is out of range.");
        }
    }
    
  • Sie möchten eine Ausnahme partiell behandeln. Ein catch-Block kann verwendet werden, um einem Fehlerprotokoll einen Eintrag hinzuzufügen und die Ausnahme dann neu auszulösen, um eine weitere Fehlerbehandlung der Ausnahme zu aktivieren. Beispiel:

    try
    {
        // try to access a resource
    }
    catch (System.UnauthorizedAccessException e)
    {
        LogError(e);  // call a custom error logging procedure
        throw e;      // re-throw the error
    }
    

Finally-Blöcke

Ein finally-Block ermöglicht die Bereinigung von in einem try-Block ausgeführten Aktionen. Falls ein finally-Block vorhanden ist, wird dieser nach dem try-Block und dem catch-Block ausgeführt. Unabhängig davon, ob eine Ausnahme ausgelöst wurde oder ob ein mit dem Ausnahmetyp übereinstimmender catch-Block gefunden wurde, wird ein finally-Block immer ausgeführt.

Der finally-Block kann verwendet werden, um Ressourcen wie Dateistreams, Datenbankverbindungen und Grafikhandles freizugeben, ohne darauf zu warten, dass der Garbage Collector Objekte in der Laufzeit abschließt. Weitere Informationen finden Sie unter using-Anweisung (C#-Referenz).

In diesem Beispiel wird mit dem finally-Block eine Datei geschlossen, die im try-Block geöffnet wurde. Beachten Sie, dass vor dem Schließen des Dateihandles dessen Zustand überprüft wird. Wenn der try-Block die Datei nicht geöffnet hat, wird der Dateihandle dennoch auf null festgelegt. Wenn die Datei hingegen erfolgreich geöffnet wurde, ohne dass eine Ausnahme ausgelöst wurde, wird der finally-Block dennoch ausgeführt, und die geöffnete Datei wird geschlossen.

System.IO.FileStream file = null;
System.IO.FileInfo fileinfo = new System.IO.FileInfo("C:\\file.txt");
try
{
    file = fileinfo.OpenWrite();
    file.WriteByte(0xF);
}
finally
{
    // check for null because OpenWrite
    // might have failed
    if (file != null)
    {
        file.Close();
    }
}

C#-Programmiersprachenspezifikation

Weitere Informationen finden Sie in den folgenden Abschnitten von C#-Programmiersprachenspezifikation:

  • 16 Ausnahmen

  • 8.9.5 Die throw-Anweisung

  • 8.10 Die try-Anweisung

Siehe auch

Konzepte

C#-Programmierhandbuch

Referenz

Ausnahmen und Ausnahmebehandlung (C#-Programmierhandbuch)

try-catch (C#-Referenz)

try-finally (C#-Referenz)

try-catch-finally (C#-Referenz)

Weitere Ressourcen

C#-Referenz