Fehlerbehandlung in C#: try/catch und mehr: von A bis Z
Jede Anwendung, selbst die eines erfahrenen Entwicklers, kann auf unvorhergesehene Situationen stoßen: Netzwerkausfall, fehlende Datei auf der Festplatte, Division durch Null oder ungültige Dateneingabe. In C# (.NET) wird für die Verwaltung solcher Situationen der Mechanismus der Ausnahmen (exceptions) verwendet. In diesem Artikel behandeln wir alles, was Sie über die Fehlerbehandlung wissen müssen: vom grundlegenden try/catch-Konstrukt bis zur Erstellung eigener Ausnahmetypen und moderner Best Practices.
1. Grundlagen: Das try/catch/finally-Konstrukt
In C# basiert die Fehlerbehandlung auf drei Schlüsselblöcken: try, catch und finally.
- try — enthält Code, der eine Ausnahme auslösen kann.
- catch — fängt eine bestimmte Ausnahme ab und behandelt sie.
- finally — wird immer ausgeführt, unabhängig davon, ob eine Ausnahme aufgetreten ist oder nicht (normalerweise zur Freigabe von Ressourcen).
try{ int[] numbers = { 1, 2, 3 }; Console.WriteLine(numbers[5]); // IndexOutOfRangeException}catch (IndexOutOfRangeException ex){ Console.WriteLine($"Fehler: {ex.Message}");}finally{ Console.WriteLine("Der finally-Block wird immer ausgeführt.");}Sie können mehrere catch-Blöcke für verschiedene Ausnahmetypen verwenden. Die Verarbeitung erfolgt von oben nach unten, daher sollten spezifischere Ausnahmen oberhalb allgemeinerer stehen.
try{ // gefährlicher Code}catch (DivideByZeroException ex){ Console.WriteLine("Division durch Null!");}catch (Exception ex) // allgemeiner Abfang{ Console.WriteLine($"Ein Fehler ist aufgetreten: {ex.Message}");}2. Ausnahmen auslösen: Der throw-Operator
Manchmal müssen Sie explizit auf eine ungültige Situation hinweisen. Dazu wird der throw-Operator verwendet. Sie können sowohl eine Standardausnahme als auch eine eigene auslösen.
public void ValidateAge(int age){ if (age < 0 || age > 150) { throw new ArgumentOutOfRangeException(nameof(age), "Das Alter muss zwischen 0 und 150 liegen."); } Console.WriteLine("Das Alter ist gültig.");}Es gibt auch das Konstrukt throw; (ohne Argumente) – es wird innerhalb eines catch-Blocks verwendet, um dieselbe Ausnahme erneut auszulösen. Dies ist nützlich, wenn Sie einen Fehler protokollieren, aber nicht unterdrücken möchten.
try{ // Code}catch (Exception ex){ Log.Error(ex); // ins Log schreiben throw; // erneutes Auslösen – die Ausnahme geht weiter}3. Erstellen eigener Ausnahmen (Custom Exceptions)
Für die Geschäftslogik ist es oft praktischer, eigene Ausnahmetypen zu verwenden. Dies macht den Code lesbarer und ermöglicht die präzise Behandlung spezifischer Fehler.
Regeln für die Erstellung einer benutzerdefinierten Ausnahme:
- Die Klasse von
Exception(oder vonApplicationException, aber besser vonException) ableiten. - Drei Standardkonstruktoren implementieren (parameterlos, mit Nachricht, mit Nachricht und innerer Ausnahme).
- Es wird empfohlen, dem Klassennamen das Suffix
Exceptionhinzuzufügen.
public class UserNotFoundException : Exception{ public UserNotFoundException() { }
public UserNotFoundException(string message) : base(message) { }
public UserNotFoundException(string message, Exception inner) : base(message, inner) { }}
// Verwendungthrow new UserNotFoundException("Benutzer mit ID 123 nicht gefunden.");4. Best Practices: Wie man sich und dem Projekt nicht schadet
Fehlerbehandlung bedeutet nicht einfach, alles in try/catch zu verpacken. Hier sind einige goldene Regeln, die Sie in C# (.NET) beachten sollten: