Ausnahmen
Bitte beachten Sie, dass sich diese Seite derzeit im Aufbau befindet und daher noch
nicht in ihrer endgültigen Form vorliegt.
Übersicht
Ausnahmen definieren
Als Basis für eigene Ausnahmen stehen in .NET zwei Klassen zur Verfügung: Exception und
ApplicationException, die sich beide im Namensraum System befinden. Ursprünglich war die
Klasse Exception den .NET-eigenen Ausnahmen als Basisklasse vorbehalten, eigendefinierte
Ausnahmen sollten von ApplicationException abgeleitet werden.
Da die Verwendung der Klasse ApplicationException in der Praxis allerdings keine Vorteile
birgt, wird ihre Verwendung seit der Version 3.0 von .NET nicht mehr empfohlen. Leiten Sie
eigene Ausnahmen statt dessen direkt von der Klasse Exception ab.
RICHTIG: Verwenden Sie die Klasse Exception als Basisklasse für eigene Ausnahmen.
Verzichten Sie aus Gründen der Zukunftssicherheit und der besseren Wartbarkeit von Code
auch unter einer Version von .NET vor 3.0 auf den Einsatz der Klasse ApplicationException
als Basisklasse für eigene Ausnahmen und verwenden Sie statt dessen die Klasse
Exception.
FALSCH: Verzichten Sie auf den Einsatz der Klasse ApplicationException als Basisklasse
für eigene Ausnahmen. Verwenden Sie statt dessen die Klasse Exception.
Implementieren Sie in einer eigendefinierten Ausnahme die Standardkonstruktoren der Klasse
Exception.
RICHTIG: Implementieren Sie in einer eigendefinierten Ausnahme die Standardkonstruktoren
der Klasse Exception.
Das folgende Beispiel zeigt, wie Sie eine Ausnahme korrekt implementieren:
| C# |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
using System;
using System.Runtime.Serialization;
public class FooException : Exception
{
public FooException()
: base()
{
}
public FooException(string message)
: base(message)
{
}
public FooException(string message, Exception innerException)
: base(message, innerException)
{
}
protected FooException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
|
Ausnahmen behandeln
Da das Fangen von Ausnahmen nur Sinn ergibt, wenn Sie die Ausnahme an der entsprechenden
Stelle auch behandeln können, fangen Sie Ausnahmen so spezifisch wie möglich. Fangen Sie
insbesondere keine allgemeinen Ausnahmetypen wie System.Exception.
FALSCH: Fangen Sie keine allgemeine Ausnahmetypen wie System.Exception, sondern fangen
Sie Ausnahmen so spezifisch wie möglich.
Fangen Sie Ausnahmen aus dem gleichen Grund nicht nur so spezifisch, sondern auch so nah
an der Fehlerquelle wie möglich, da Sie dann die besten Möglichkeiten haben, gezielt auf
die Ausnahme eingehen zu können.
RICHTIG: Fangen Sie Ausnahmen so lokal wie möglich.
Da dennoch Ausnahmen auftreten können, die Sie nicht behandeln, schreiben Sie für die
Methode Main und für die Hauptmethode jedes Threads einen allgemeinen
try /
catch-Block, der die Ausnahme
protokolliert und die Anwendung beendet, so dass Ausnahmen nicht dem Anwender angezeigt
werden.
RICHTIG: Schreiben Sie auf der obersten Anwendungs- und Threadebene einen allgemeinen
try /
catch-Block.
Wenn Sie die gefangene Ausnahme nicht behandeln können, sondern diese an die nächsthöhere
Ebene weiterreichen müssen, lösen Sie diese nicht erneut aus, sondern verwenden Sie das
Schlüsselwort
throw ohne Parameter, um den Aufrufstapel zu
erhalten.
FALSCH: Lösen Sie eine Ausnahme nicht erneut aus, um sie an die nächsthöhere Ebene
weiterzureichen, sondern verwenden Sie das Schlüsselwort
throw
ohne Parameter.
Das folgende Beispiel zeigt, wie Sie eine Ausnahme korrekt an die nächsthöhere Ebene
weiterreichen:
| C# |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
using System;
public class Foo
{
public void Bar()
{
try
{
throw new NotImplementedException();
}
catch
{
throw;
}
}
}
|
Da das Auslösen einer Ausnahme eine aufwändige Analyse des Methodenstapels und das Erzeugen
einiger Objekte erfordert, verwenden Sie Ausnahmen nicht, um logische Abläufe innerhalb
der Anwendung zu implementieren.
FALSCH: Verwenden Sie Ausnahmen nicht, um logische Abläufe zu implementieren. Verwenden
Sie statt dessen Kontrollstrukturen wie beispielsweise Bedingungen und Schleifen.
Falls ein Fehler im Vorfeld abgefangen werden kann, nutzen Sie diese Möglichkeit und
vermeiden Sie so das unnötige Auslösen von Ausnahmen.
FALSCH: Vermeiden Sie das unnötige Auslösen von Ausnahmen und vermeiden Sie das
Auftreten von Fehlern nach Möglichkeit bereits im Vorfeld.
Falls Sie Daten von einem Typ in einen anderen konvertieren wollen, verwenden Sie nach
Möglichkeit die Methode TryParse des Zieltyps und prüfen Sie deren Rückgabewert. Ziehen
Sie diese Möglichkeit dem Einsatz der Methode Parse und einem umgebenden
try /
catch-Block vor, um das unnötige
Auslösen von Ausnahmen zu vermeiden.
Vermeiden Sie den Einsatz der Methode Parse und einem umgebenden
try /
catch-Block und verwenden Sie
statt dessen die Methode TryParse, sofern verfügbar.