try-catch (C#-Referenz)

Die try-catch-Anweisung besteht aus einem try-Block, auf den eine oder mehrere catch-Klauseln folgen, die Handler für verschiedene Ausnahmen angeben. Beim Auslösen einer Ausnahme sucht die CLR (Common Language Runtime) nach der catch-Anweisung, die diese Ausnahme behandelt. Falls die derzeit ausgeführte Methode keinen solchen catch-Block enthält, sucht die CLR nach der Methode, mit der die aktuelle Methode aufgerufen wurde, usw. bis zur nächsten Aufruflsite. Wird kein catch-Block gefunden, zeigt die CLR eine nicht bearbeitete Ausnahmemeldung für den Benutzer an und hält die Ausführung des Programms an.

Der try-Block enthält den überwachten Code, der möglicherweise die Ausnahme verursacht. Der Block wird solange ausgeführt, bis er erfolgreich abgeschlossen oder eine Ausnahme ausgelöst wird. Der folgende Versuch, ein null-Objekt umzuwandeln, löst z. B. die NullReferenceException-Ausnahme aus:

object o2 = null;
try
{
    int i2 = (int)o2;   // Error
}

Obwohl die catch-Klausel ohne Argumente verwendet wird, sodass sie jeden Ausnahmetyp abfängt, wird dies nicht empfohlen. Im Allgemeinen sollten Sie nur jene Ausnahmen abfangen, die Sie wiederherstellen können. Deshalb sollten Sie immer ein von System.Exception abgeleitetes Objektargument angeben:

catch (InvalidCastException e) 
{
}

Es darf mehr als eine bestimmte catch-Klausel in derselben try-catch-Anweisung verwendet werden. In diesem Fall ist die Reihenfolge der catch-Klauseln von Bedeutung, da die catch-Klauseln nacheinander überprüft werden. Präziser definierte Ausnahmen sollten vor weniger präzisen abgefangen werden. Der Compiler erzeugt einen Fehler, wenn Sie Ihre catch-Blöcke so anordnen, dass ein Block, der sich weiter unten befindet, nie erreicht werden kann.

Mit einer throw-Anweisung kann in einem catch-Block die Ausnahme erneut ausgelöst werden, die von der catch-Anweisung abgefangen wird. Im folgenden Beispiel werden Quellinformationen aus einer IOException-Ausnahme extrahiert, und anschließend wird die Ausnahme in der übergeordneten Methode ausgelöst.

catch (FileNotFoundException e)
{
    // FileNotFoundExceptions are handled here.
}
catch (IOException e)
{
    // Extract some information from this exception, and then 
    // throw it to the parent method.
    if (e.Source != null)
        Console.WriteLine("IOException source: {0}", e.Source);
    throw;
}

Sie können eine Ausnahme abfangen und eine andere Ausnahme auslösen. In diesem Fall geben Sie die Ausnahme an, die Sie als innere Ausnahme erfasst haben, wie im folgenden Beispiel gezeigt.

catch (InvalidCastException e) 
{
    // Perform some action here, and then throw a new exception.
    throw new YourCustomException("Put your error message here.", e);
}

Sie können eine Ausnahme auch erneut auslösen, wenn eine angegebene Bedingung TRUE ist, wie im folgenden Beispiel gezeigt.

catch (InvalidCastException e)
{
    if (e.Data == null)
    {
        throw;
    }
    else
    {
        // Take some action.
    }
 }

Initialisieren Sie von innerhalb eines try-Blocks nur darin deklarierte Variablen. Andernfalls kann eine Ausnahme auftreten, bevor die Ausführung des Blocks abgeschlossen ist. Im folgenden Codebeispiel wird beispielsweise die Variable n innerhalb des try-Blocks initialisiert. Beim Versuch, diese Variable außerhalb des try-Blocks in der Write(n)-Anweisung zu verwenden, wird ein Compilerfehler generiert.

static void Main() 
{
    int n;
    try 
    {
        // Do not initialize this variable here.
        n = 123;
    }
    catch
    {
    }
    // Error: Use of unassigned local variable 'n'.
    Console.Write(n);
}

Weitere Informationen über catch-Klauseln finden Sie unter try-catch-finally.

Beispiel

Im folgenden Beispiel enthält der try-Block einen Aufruf der ProcessString-Methode, der möglicherweise eine Ausnahme verursacht. Die catch-Klausel enthält den Ausnahmehandler, der lediglich eine Meldung auf dem Bildschirm anzeigt. Wenn die throw-Anweisung aus MyMethod heraus aufgerufen wird, sucht das System nach der catch-Anweisung und zeigt die Meldung Exception caught an.

    class TryFinallyTest
{
    static void ProcessString(string s)
    {
        if (s == null)
        {
            throw new ArgumentNullException();
        }
    }

    static void Main()
    {
        string s = null; // For demonstration purposes.

        try
        {            
            ProcessString(s);
        }

        catch (Exception e)
        {
            Console.WriteLine("{0} Exception caught.", e);
        }
    }
}
    /*
    Output:
    System.ArgumentNullException: Value cannot be null.
       at TryFinallyTest.Main() Exception caught.
     * */

In diesem Beispiel werden zwei catch-Anweisungen verwendet. Die präziseste Ausnahme, die sich an erster Stelle befindet, wird abgefangen.

class ThrowTest3
{
    static void ProcessString(string s)
    {
        if (s == null)
        {
            throw new ArgumentNullException();
        }
    }

    static void Main()
    {
        try
        {
            string s = null;
            ProcessString(s);
        }
        // Most specific:
        catch (ArgumentNullException e)
        {
            Console.WriteLine("{0} First exception caught.", e);
        }
        // Least specific:
        catch (Exception e)
        {
            Console.WriteLine("{0} Second exception caught.", e);
        }
    }
}
/*
 Output:
 System.ArgumentNullException: Value cannot be null.
 at Test.ThrowTest3.ProcessString(String s) ... First exception caught.
*/

Wenn Sie im vorherigen Beispiel mit der am wenigsten präzisen catch-Klausel beginnen, wird die folgende Fehlermeldung angezeigt:

A previous catch clause already catches all exceptions of this or a super type ('System.Exception')

Um die am wenigsten präzise Ausnahme dennoch abzufangen, ersetzen Sie die throw-Anweisung durch die Folgende:

throw new Exception();

C#-Programmiersprachenspezifikation

Weitere Informationen finden Sie in der C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.

Siehe auch

Aufgaben

Gewusst wie: Explizites Auslösen von Ausnahmen

Referenz

C#-Schlüsselwörter

try, catch, and throw Statements (C++)

Ausnahmebehandlungsanweisungen (C#-Referenz)

throw (C#-Referenz)

try-finally (C#-Referenz)

Konzepte

C#-Programmierhandbuch

Weitere Ressourcen

C#-Referenz

Änderungsprotokoll

Datum

Versionsgeschichte

Grund

Juli 2010

Aktualisierte throw-Beispiele.

Kundenfeedback.