Share via


Ausnahmebehandlung (C#-Programmierhandbuch)

Ein try-Block wird von C#-Programmierern verwendet, um Code zu partitionieren, der möglicherweise von einer Ausnahme betroffen ist. Mit zugeordneten catch-Blöcken werden sich ergebende Ausnahmen behandelt. Ein finally-Block enthält Code, der unabhängig davon ausgeführt wird, ob eine Ausnahme im try-Block ausgelöst wird, z. B. Freigeben von Ressourcen, die im try-Block zugeordnet werden. Ein try-Block erfordert einen oder mehrere zugeordneten catch-Blöcke oder einen finally-Block oder beides.

Die folgenden Beispiele zeigen eine try-catch-Anweisung, eine try-finally-Anweisung und eine try-catch-finally-Anweisung.

try
{
    // Code to try goes here.
}
catch (SomeSpecificException ex)
{
    // Code to handle the exception goes here. 
    // Only catch exceptions that 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 goes here.
}
finally
{
    // Code to execute after the try block goes here.
}
try
{
    // Code to try goes here.
}
catch (SomeSpecificException ex)
{
    // Code to handle the exception goes here.
}
finally
{
    // Code to execute after the try (and possibly catch) blocks  
    // goes here.
}

Ein try-Block ohne einen catch- oder finally-Block verursacht einen Compilerfehler.

Catch-Blöcke

Ein catch-Block kann den abzufangenden Ausnahmetyp angeben. Die Typspezifikation wird Ausnahmefilter genannt. Der Ausnahmetyp muss von Exception abgeleitet sein. Geben Sie im Allgemeinen Exception nicht als Ausnahmefilter an, es sei denn, Sie können alle Ausnahmen, die im try-Block ausgelöst werden können, behandeln, oder Sie haben eine throw-Anweisung am Ende des catch-Blocks eingefügt.

Mehrere catch-Blöcke mit verschiedenen Ausnahmefiltern können miteinander verkettet werden. Die catch-Blöcke werden von oben nach unten im Code ausgewertet, aber nur ein catch-Block wird für jede ausgelöste Ausnahme 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 übereinstimmenden Ausnahmefilter angibt, wird ein catch-Block ohne Filter ausgewählt, wenn in der Anweisung vorhanden. Es ist wichtig, catch-Blöcke mit den spezifischsten (den am stärksten abgeleiteten) Ausnahmetypen zuerst zu positionieren.

Sie sollten Ausnahmen abfangen, wenn die folgenden Bedingungen gelten:

  • Sie haben ausreichende Kenntnisse darüber, aus welchem Grund die Ausnahme ausgelöst werden kann, und Sie können eine bestimmte Wiederherstellung implementieren, z. B. Auffordern des Benutzers, einen neuen Dateinamen einzugeben, wenn Sie ein FileNotFoundException-Objekt abfangen.

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

    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 teilweise behandeln, bevor Sie diese für zusätzliche Behandlung übergeben. Im folgenden Beispiel wird ein catch-Block verwendet, um einen Eintrag einem Fehlerprotokoll hinzuzufügen, bevor die Ausnahme erneut ausgelöst wird.

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

Finally-Blöcke

Mithilfe eines finally-Blocks können Sie Aktionen bereinigen, die in einem try-Block ausgeführt werden. Falls vorhanden, wird der finally-Block zuletzt ausgeführt wird, nach dem try-Block und einem entsprechenden catch-Block. Unabhängig davon, ob eine Ausnahme ausgelöst wurde oder 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).

Im folgenden Beispiel wird der finally-Block verwendet, um eine Datei zu schließen, die im try-Block geöffnet wurde. Beachten Sie, dass vor dem Schließen der Datei der Zustand des Dateihandles überprüft wird. Wenn der try-Block die Datei nicht öffnen kann, hat das Dateihandle weiterhin den Wert null, und der finally-Block versucht nicht, sie zu schließen. Wenn alternativ dazu die Datei erfolgreich im try-Block geöffnet wird, schließt der finally-Block die geöffnete Datei.

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 erhalten Sie unter C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.

Siehe auch

Referenz

Ausnahmen und Ausnahmebehandlung (C#-Programmierhandbuch)

try-catch (C#-Referenz)

try-finally (C#-Referenz)

try-catch-finally (C#-Referenz)

using-Anweisung (C#-Referenz)

Konzepte

C#-Programmierhandbuch

Weitere Ressourcen

C#-Referenz