English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C# Ausnahmebehandlung

Hier lernen Sie, wie man in C# mit try, catch und finally-Blöcken Ausnahmen behandelt.

Es muss in der Anwendung Ausnahmen behandelt werden, um Programmabstürze und unerwartete Ergebnisse zu verhindern, Ausnahmen zu protokollieren und andere Funktionen fortzuführen. C# bietet eingebaute Unterstützung zur Behandlung von Ausnahmen durch die Verwendung von try, catch und finally-Blöcken.

Syntax:

try
{
    // Der Code hier könnte eine Ausnahme verursachen
}
catch
{
    // Behandeln Sie hier die Ausnahme
}
finally
{
    // Endreinigungscode
}

try-Block:Jeglicher verdächtiger Code, der eine Ausnahme auslösen könnte, sollte in einem try{ }-Block platziert werden. Wenn während der Ausführung eine Ausnahme auftritt, springt der Kontrollfluss zum ersten passenden catch-Block.

catch Blöcke:catch-Blöcke sind Ausnahmebehandlungsblöcke, in denen Sie einige Aktionen ausführen können, z.B. das Protokollieren und Überprüfen von Ausnahmen. catch-Blöcke nehmen einen Exception-Typ als Parameter an, mit dem Sie detaillierte Informationen über die Ausnahme erhalten können.

finally Blöcke:finally wird unabhängig davon, ob eine Ausnahme ausgelöst wird oder nicht, immer ausgeführt. Der finally-Block sollte normalerweise in einem Block verwendet werden, um Ressourcen freizugeben, z.B. die Schließung von im try-Block geöffneten Streams oder Dateiobjekten.

Wenn Sie einen nicht-numerischen Text eingeben, kann eine Ausnahme ausgelöst werden.

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Geben Sie eine Zahl ein: ");
        var num = int.Parse(Console.ReadLine());
        Console.WriteLine($"Das Quadrat von {num} ist {num"); * num");
    }
}

Um mögliche Ausnahmen im obigen Beispiel zu behandeln, verpacken Sie den Code in einen try-Block und behandeln Sie die Ausnahme im catch-Block, wie folgt.

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Console.WriteLine("Geben Sie eine Zahl ein: ");
            var num = int.parse(Console.ReadLine());
            Console.WriteLine($"Das Quadrat von {num} ist {num"); * num");
        }
        catch
        {
            Console.Write("Ein Fehler ist aufgetreten.");
        }
        finally
        {
            Console.Write("Re");-versuchen Sie es mit einer anderen Zahl.");
        }
    }
}

Im obigen Beispiel verpacken wir diesen Code in einen try-Block. Wenn im try-Block eine Ausnahme auftritt, springt das Programm zum catch-Block. Innerhalb des catch-Blocks zeigen wir eine Nachricht an, um dem Benutzer Informationen über seinen Fehler zu geben, und im finally-Block zeigen wir eine Nachricht über die nach der Ausführung des Programms durchzuführenden Aktionen an.

Der try-Block muss einem catch- oder finally- oder beiden Blöcken folgen. Gibt es im try-Block keine catch- oder finally-Blöcke, wird ein Compilerfehler ausgegeben.

Im Idealfall sollte der catch-Block Parameter einer eingebauten oder benutzerdefinierten Exception-Klasse enthalten, um detaillierte Fehlerinformationen zu erhalten. Nachfolgend wird der type-Parameter von Exception verwendet, um alle Arten von Ausnahmen zu fangen.

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Console.WriteLine("Geben Sie eine Zahl ein: ");
            var num = int.parse(Console.ReadLine());
            Console.WriteLine($"Das Quadrat von {num} ist {num"); * num");
        }
        catch(Exception ex)
        {
            Console.Write("Fehlerinfo:"); + ex.Message);
        }
        finally
        {
            Console.Write("Re");-versuchen Sie es mit einer anderen Zahl.");
        }
    }
}

Ausnahme-Filter

Sie können mehrere Blöcke mit catch und verschiedenen Ausnahmearten verwenden. Dies wird als Ausnahme-Filter bezeichnet. Ausnahme-Filter sind nützlich, wenn Sie verschiedene Arten von Ausnahmen unterschiedlich behandeln möchten.

class Program
{
    static void Main(string[] args)
    {
        Console.Write("Bitte geben Sie eine Zahl ein, um sie zu teilen"); 100: ");
        
        try
        {
            int num = int.Parse(Console.ReadLine());
            int result = 100 / num;
            Console.WriteLine("100 / {0} = {1}
        }
        catch(DivideByZeroException ex)
        {
            Console.Write("Kann durch Null geteilt werden. Bitte versuchen Sie es noch einmal.");
        }
        catch(InvalidOperationException ex)
        {
            Console.Write("Ungültige Operation. Bitte versuchen Sie es noch einmal.");
        }
        catch(FormatException ex)
        {
            Console.Write("Ungültiges Format. Bitte versuchen Sie es noch einmal.");
        }
        catch(Exception ex)
        {
            Console.Write("Es ist ein Fehler aufgetreten! Bitte versuchen Sie es noch einmal.");
        }
    }
}

Im obigen Beispiel haben wir mehrere Blöcke mit verschiedenen Ausnahmearten angegeben, die catch haben. Wir können dem Benutzer eine angemessene Nachricht anzeigt, sodass der Benutzer den Fehler nicht noch einmal begeht.

Hinweis:
Mehrfachcatch-Blöcke mit gleicher Ausnahmeart sind nicht erlaubt. Ein catch-Block mit der Basisklasse der Ausnahme muss immer der letzte Block sein.

Ungültiger catch-Block

In einem try..catch-Ausdruck ist der Einsatz eines catch-Blocks ohne Parameter und eines catch-Blocks mit Exception-Parameter nicht erlaubt, da beide die gleiche Aktion ausführen.

try
{
    //Code, der möglicherweise Ausnahmen verursacht
}
catch //catch und catch(Exception 异常)不能同时存在
{ 
    Console.WriteLine("Exception aufgetreten");
}
catch(Exception ex) //catch und catch(异常异常)不能同时存在
{
    Console.WriteLine("Exception aufgetreten");
}

Außerdem muss der catch-Block ohne Parameter catch {} oder der allgemeine catch-Block catch (Exception ex){} immer der letzte Block sein. Wenn nach dem catch {}- oder catch (Exception ex)-Block noch weitere catch-Blöcke folgen, gibt der Compiler einen Fehler aus.

    Beispiel: Ungültige catch-Catchen

try
{
    //Code, der möglicherweise Ausnahmen verursacht
}
catch
{ 
    // Dieser Catch-Block muss der letzte sein
}
catch (NullReferenceException nullEx)
{
    Console.WriteLine(nullEx.Message);
}
catch (InvalidCastException inEx)
{
    Console.WriteLine(inEx.Message);
}

finally-Block

finally-Blöcke sind optionale Blöcke und sollten nach try- oder catch-Blöcken platziert werden. finally-Blöcke werden immer ausgeführt, egal ob eine Ausnahme aufgetreten ist oder nicht. finally-Blöcke werden normalerweise für Bereinigungscode verwendet, z.B. für nicht verwaltete Objekte.

    Beispiel: finally-Block

static void Main(string[] args)
{
    FileInfo file = null;
    try
    {
        Console.Write("Geben Sie einen Dateinamen ein, um zu schreiben: ");
        string fileName = Console.ReadLine();
        file = new FileInfo(fileName);
        file.AppendText("Hallo Welt!")
    }
    catch(Exception ex)
    {
        Console.WriteLine("Ein Fehler ist aufgetreten: {0}", ex.Message);
    }
    finally
    {
        // Hier wird das Dateiobjekt bereinigt;
        file = null;
    }
}
finally kann nicht verwendet werden mehrere Blöcke. Außerdem dürfen finally-Blöcke keine return-, continue- oder break-Schlüsselwörter enthalten. Es ist nicht erlaubt, den Control-Flow aus dem finally-Block zu verlassen.

Verschränkte try-catch

C# ermöglicht die Verwendung von nested try-Beim Catchen eines Blocks. Wenn nested try verwendet wird-Beim Catchen eines Blocks wird die Ausnahme im ersten abgestimmten Block erfasst, der sich nach dem try-Block, in dem die Ausnahme aufgetreten ist, befindet.

static void Main(string[] args)
{
    var divider = 0;
    try
    {
        try
        {
            var result = 100/divider;
        }
        catch
        {
            Console.WriteLine("Inner catch");
        }
    }
    catch
    {
        Console.WriteLine("Außen catch");
    }
}
Ausgabe:
Innerer catch

catch in dem obigen Beispiel wird ein interner Block ausgeführt, weil es der erste Block ist, der alle Arten von Ausnahmen behandelt.

Wenn es keinen internen catch-Block gibt, der mit dem Typ der ausgelösten Ausnahme übereinstimmt, fließt die Kontrolle in den externen catch-Block, bis ein geeigneter Ausnahme-Filter gefunden wird. Sehen Sie sich das folgende Beispiel an.

static void Main(string[] args)
{
    var divider = 0;
    try
    {
        try
        {
            var result = 100/divider;
        }
        catch(NullReferenceException ex)
        {
            Console.WriteLine("Inner catch");
        }
    }
    catch
    {
        Console.WriteLine("Außen catch");
    }
}
Ausgabe:
Außen catch

Im obigen Beispiel wird eine Typausnahme DivideByZeroException ausgelöst. Da der interne catch-Block nur NullReferenceTypeException behandelt, wird die Ausnahme vom äußeren catch-Block behandelt.