C#-Beginner: Exception-Handling unter C#

02.03.06 - .NET, Base Framework
Beitrag von Norbert Eder
 Das Thema Exception-Behandlung scheint bei vielen .NET Programmierern noch nicht richtig angekommen zu sein. Immer wieder finden sich in diversen Beispielen und Fragen traurige Konstrukte, die hauptsächlich negative Erscheinungen zu Tage fördern. Also Beispiel sei hier ein neulich gesichteter Code gezeigt werden (nicht kopieren!!!!!):


try
{
StreamReader sr = new StreamReader("path");
string text = sr.ReadToEnd();
sr.Close();
}
catch (Exception ex) {}


Das Ergebnis? Nun, ist die Datei nicht vorhanden wird eine Exception geworfen und auch abgefangen, aber es passiert damit nichts. Es erfolgt weder eine Meldung an den User, noch ein Log-Eintrag, um etwaige Fehler zu einem späteren Zeitpunkt nachvollziehen zu können. Ein weiterer Effekt ist, dass beim "Testen" durch den Entwickler "alles funktioniert" - was natürlich nicht stimmt.

Nun gut, aber wie soll das Exception Handling dann wirklich umgesetzt werden? Ganz einfach. Der grundlegende try-catch-Block sieht so aus:


try {
// Implementierung
} catch (IOException ex) {
// Fehlerbehandlung für IO-Fehler
} catch (Exception ex) {
// Fehlerbehandlung für andere Fehler
} finally {
// Abschlussarbeiten
}


Hier noch eine genaue Beschreibung:

try: Im try-Teil des gesamten Blockes erfolgt die Implementierung der tatsächlichen Funktion.

catch: Hier ist die Fehlerbehandlung zu implementieren. Dies kann realisiert werden, indem die Fehlermeldungen bzw. zusätzliche Einträge in eine Log-Datei geschrieben werden oder eine User-Interaktion verlangt wird. Wie oben gezeigt, können mehrere Exceptions gezielt abgefangen und behandelt werden. In der MSDN finden sich zu allen Methoden auch Angaben darüber, welche Exceptions geworfen werden. Prinzipiell ist mit diesen Exceptions zu arbeiten und nicht direkt mit Exception selbst.

finally: Dieser Teil des Blockes wird in jedem Fall ausgeführt, also sowohl nach erfolgreichem Durchlauf des try-Teiles, als auch im Falle eines Fehlers. Dadurch bietet es sich an, im finally-Block Aufräumarbeiten durchzuführen. Dies kann beispielsweise das Schließen einer Datenbank-Verbindung sein.

Beim catch-Block muss nicht zwingend ein Typ angegeben werden. Ist dies nicht der Fall, dann werden sämtliche Exceptions behandelt. Von dieser Schreibweise würde ich jedoch eher abraten:


try {

} catch {

}


Des weiteren sollten Exception nicht für die Ablaufsteuerung einer Anwendung verwendet werden. Darunter wird verstanden, dass gezielt auf Exceptions abgefragt wird, um aufgrund des Exception-Typs zu entscheiden, welcher weitere Code anschließend ausgeführt wird. Exceptions sind sehr "teuer". Dies bedeutet, dass dadurch viele Ressourcen verbraucht werden. Daher sind Exceptions auch als solche zu behandeln.

Natürlich besteht auch die Möglichkeit eigene Exceptions zu implementieren. Dies macht vor allem bei der Entwicklung von größeren Frameworks (die auch von anderen Entwicklern benutzt werden) Sinn. Folgendes Beispiel soll eine eigene Exception verdeutlichen:


using System;
class MyException : ApplicationException
{
public MyException(string str)
{
Console.WriteLine(str);
}
}


Wie zu erkennen ist, ist von der Basisklasse ApplicationException abzuleiten. Der Konstruktor erhält einen Parameter und damit ist die einfachste Variante einer benutzerdefinierten Exception fertig. Weitere Möglichkeiten können aus der MSDN bezogen werden.

Zum Schluss möchte ich noch kurz ansprechen, wie der Programmierer selbst Exceptions werfen kann. Dies wird mittels des Schlüsselwortes throw getan:


throw new MyException("Eine benutzerdefinierte Exception ist aufgetreten");


Eine so geworfene Exception muss natürlich auch entsprechend behandelt werden.

Referenzen und weiterführende Artikel:
[1] Exception Management Architecture Guide
[2] Exception Class

 


Christian

02.03.06
 begin{oberlehrer} Ist es nicht auch guter Stil, eigene Exceptions lieber von ApplicationException abzuleiten? Irgendwie teilt .net doch in die ExceptionWelt in ApplicationException und SystemException, die von Exception abgeleitet sind...end{oberlehrer}

Und die Geschichte, exceptions nicht als Flusssteuerung zu verwenden, gestaltet sich manchmal etwas unschön. Ich darf in letzter Zeit vb.net hacken und habe häufig keine Ahnung, wie ich denn Objekte in VB auf deren Gültigkeit prüfe. isnothing oder sonstwas zieht irgendwie nicht immer. in C# hatte gab es mit sowas nie Probleme. Auch, wenn es kein schöner Stil ist halte ich denn manchmal doch für zulässig, einfach mal eine Exception als Datenkorrigierer einzusetzen ;-). Man sollte dann sicherlich drauf achten, dass der dadurch teure code nicht Millardenfach durchlaufen wird.

 


Norbert

02.03.06
 Danke für die Rückmeldung. In der Tat ist es schöner von ApplicationException abzuleiten, praktisch ergibt sich daraus jedoch kaum ein Unterschied.
Zum Thema Flusssteuerung: In manchen Fällen ist die Flusssteuerung durch Exceptions der einfachste Weg, sollte jedoch wirklich nur dann verwendet werden, kein anderer Weg zur Verfügung steht.
 


Timo

19.08.11
 Das kann ich bestätigen.

Exceptions schmeißen und dann ohne etwas zu tun ist eine Todsünde. Schlimmer als sie garnicht erst zu fangen. Da ist es mir schon lieber, wenn eine generische Exception abgefangen und "irgendwie" behandelt wird. Sonst macht das alles keinen Sinn.
 


Kommentar hinzufügen

Bitte das Formular ausfüllen, um Deinen Kommentar hinzuzufügen.









Spezial-Code einfügen: