try-catch (C#-Referenz)

Aktualisiert: November 2007

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 bereits von der catch-Anweisung abgefangen wurde. Beispiel:

catch (InvalidCastException e) 
{
    throw (e);    // Rethrowing exception e
}

Sie können auch eine neue Ausnahme auslösen. Geben Sie dazu die Ausnahme an, die Sie als innere Ausnahme abfangen:

catch (InvalidCastException e) 
{
   // Can do cleanup work here.
    throw new CustomException("Error message here.", e);
}

Soll die Ausnahme, die momentan von einer catch-Klausel ohne Parameter behandelt wird, erneut ausgelöst werden, verwenden Sie die throw-Anweisung ohne Argumente. Beispiel:

catch
{
    throw;
}

In einem try-Block dürfen nur die darin deklarierten Variablen initialisiert werden. Andernfalls kann eine Ausnahme auftreten, bevor die Ausführung des Blocks abgeschlossen ist. Im folgenden Codebeispiel wird beispielsweise die Variable x innerhalb des try-Blocks initialisiert. Beim Versuch, diese Variable außerhalb des try-Blocks in der Write(x)-Anweisung zu verwenden, wird folgender Compilerfehler generiert: Compilerfehler CS0165.

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

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

Beispiel

In diesem 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 TryFinallyTest.Main() 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 den folgenden Abschnitten von C#-Programmiersprachenspezifikation:

  • 5.3.3.13 try-catch-Anweisungen

  • 8.10 Die try-Anweisung

  • 16 Ausnahmen

Siehe auch

Aufgaben

Gewusst wie: Explizites Auslösen von Ausnahmen

Konzepte

C#-Programmierhandbuch

Referenz

C#-Schlüsselwörter

The try, catch, and throw Statements

Ausnahmebehandlungsanweisungen (C#-Referenz)

throw (C#-Referenz)

try-finally (C#-Referenz)

Weitere Ressourcen

C#-Referenz