Eine benutzerdefinierte Ausnahme ist jede Klasse, die du in deinem Code definierst und die von System.Exception abgeleitet ist. Für sie gelten alle Regeln der Klassenvererbung, doch zusätzlich behandeln der Compiler und die Laufzeitumgebung solche Klassen auf besondere Weise: Ihre Instanzen lassen sich außerhalb des normalen Kontrollflusses auslösen und abfangen, wie in der Übung exceptions besprochen. Benutzerdefinierte Ausnahmen kannst du in jeder Hinsicht so verwenden wie Ausnahmen der Laufzeitumgebung und der Microsoft Base Class Library.
Diese besondere Behandlung gilt nur für Klassen, die von Exception abgeleitet sind. Instanzen jedes anderen Typs kannst du nicht auslösen.
Benutzerdefinierte Ausnahmen werden oft verwendet, um zusätzliche Informationen wie eine Nachricht und andere relevante Daten an die abfangenden Routinen weiterzugeben. Diese können dann in Logs aufgezeichnet, einem Benutzer gemeldet oder vielleicht für einen erneuten Versuch verwendet werden. System.Exception bietet praktische Datenmember und passende Konstruktoren, um eine Nachricht und die „innere“ Ausnahme aufzunehmen.
Konventionsgemäß enden die Namen von Ausnahmeklassen auf „Exception“, z. B. MyTerribleException.
Benutzerdefinierte Ausnahmen zu verwenden, um Ausnahmen von Drittanbietern zu umhüllen und zu erweitern, ist zwar ein häufig anzutreffendes Muster, doch die allgemeine Empfehlung lautet, sie außerhalb dieses Anwendungsfalls nicht allzu großzügig im eigenen Code einzusetzen. Es gilt als Anti-Pattern. Diese Sichtweise wird angefochten, und beide Seiten der Diskussion findest du in diesem Stack-Exchange-Beitrag.
Dieser Artikel ist eine gute Einführung in benutzerdefinierte Ausnahmen.
Im Rahmen ihrer Anleitung zum Erstellen und Auslösen von Ausnahmen empfiehlt das .NET-Team, dass benutzerdefinierte Ausnahmen eine Reihe von Komfortkonstruktoren haben sollten. Für die meisten Zwecke ist die unten gezeigte Kombination geeignet.
public class IncompleteExerciseException : System.Exception
{
public IncompleteExerciseException() : base() { }
public IncompleteExerciseException(string message) : base(message) { }
public IncompleteExerciseException(string message, System.Exception inner) : base(message, inner) { }
}