21 Ausnahmen
21.1 Allgemein
Ausnahmen in C# bieten eine strukturierte, einheitliche und typsichere Methode zur Behandlung von Fehlerbedingungen auf Systemebene und Anwendungsebene.
21.2 Ursachen von Ausnahmen
Ausnahmen können auf zwei verschiedene Arten ausgelöst werden.
- Eine
throw
Anweisung (§13.10.6) löst sofort und bedingungslos eine Ausnahme aus. Control erreicht niemals die Anweisung unmittelbar nach derthrow
. - Bestimmte außergewöhnliche Bedingungen, die während der Verarbeitung von C#-Anweisungen und Ausdrücken auftreten, führen dazu, dass eine Ausnahme in bestimmten Situationen ausgelöst wird, wenn der Vorgang nicht normal abgeschlossen werden kann. Eine Liste der verschiedenen Ausnahmen, die auf diese Weise ausgelöst werden können, finden Sie unter §21.5 .
Beispiel: Ein Ganzzahlteilungsvorgang (§12.10.3) löst einen
System.DivideByZeroException
Aus, wenn der Nenner null ist. Endbeispiel
21.3 Die System.Exception-Klasse
Die System.Exception
Klasse ist der Basistyp aller Ausnahmen. Diese Klasse verfügt über einige wichtige Eigenschaften, die von allen Ausnahmen gemeinsam verwendet werden:
Message
ist eine schreibgeschützte Eigenschaft des Typsstring
, die eine lesbare Beschreibung des Grunds für die Ausnahme enthält.InnerException
ist eine schreibgeschützte Eigenschaft vom TypException
. Wenn der Wert nicht istnull
, bezieht er sich auf die Ausnahme, die die aktuelle Ausnahme verursacht hat. (Das heißt, die aktuelle Ausnahme wurde in einem Catch-Block ausgelöst, der dieInnerException
.) Andernfalls lautetnull
der Wert , der angibt, dass diese Ausnahme nicht durch eine andere Ausnahme verursacht wurde. Die Anzahl der ausnahmeobjekte, die auf diese Weise miteinander verkettet sind, kann beliebig sein.
Der Wert dieser Eigenschaften kann in Aufrufen des Instanzkonstruktors angegeben werden.System.Exception
21.4 Behandlung von Ausnahmen
Ausnahmen werden von einer try
Anweisung behandelt (§13.11).
Wenn eine Ausnahme ausgelöst wird (§21.2), sucht das System nach der nächstgelegenen Catch-Klausel, die die Ausnahme verarbeiten kann, wie durch den Laufzeittyp der Ausnahme bestimmt. Zunächst wird die aktuelle Methode nach einer lexikalisch eingeschlossenen try
Anweisung gesucht, und die zugeordneten catch
Klauseln der try
Anweisung werden in der Reihenfolge berücksichtigt. Wenn dies fehlschlägt, wird die Methode, die die aktuelle Methode aufgerufen hat, nach einer lexikalisch eingeschlossenen try
Anweisung gesucht, die den Punkt des Aufrufs der aktuellen Methode einschließt. Diese Suche wird fortgesetzt, bis eine catch
Klausel gefunden wird, die die aktuelle Ausnahme behandeln kann, indem eine Ausnahmeklasse benannt wird, die von derselben Klasse oder einer Basisklasse des Laufzeittyps der ausgelösten Ausnahme ist. Eine catch
Klausel, die keine Ausnahmeklasse benamen, kann eine Ausnahme behandeln.
Sobald eine Übereinstimmende catch
Klausel gefunden wurde, bereitet das System die Steuerung an die erste Anweisung der catch
Klausel vor. Bevor die Ausführung der catch
Klausel beginnt, führt das System zunächst alle Klauseln aus, finally
die mit Anweisungen verknüpft try
wurden, die geschachtelt sind, als die Klausel, die die Ausnahme erfasst hat.
Wenn keine übereinstimmende catch
Klausel gefunden wird:
- Wenn die Suche nach einer übereinstimmenden
catch
Klausel einen statischen Konstruktor (§15.12) oder einen initialisierer statischen Feld erreicht, wird anSystem.TypeInitializationException
der Stelle ausgelöst, an der der Aufruf des statischen Konstruktors ausgelöst wurde. Die innere Ausnahme derSystem.TypeInitializationException
Ausnahme enthält die Ausnahme, die ursprünglich ausgelöst wurde. - Andernfalls, wenn eine Ausnahme während der Finalizerausführung auftritt und diese Ausnahme nicht erfasst wird, wird das Verhalten nicht angegeben.
- Andernfalls wird die Ausführung des Threads beendet, wenn die Suche nach übereinstimmenden
catch
Klauseln den Code erreicht, der den Thread anfangs gestartet hat. Die Auswirkungen dieser Beendigung werden durch implementierungsdefiniert.
21.5 Allgemeine Ausnahmeklassen
Die folgenden Ausnahmen werden von bestimmten C#-Vorgängen ausgelöst.
Ausnahmetyp | Beschreibung |
---|---|
System.ArithmeticException |
Eine Basisklasse für Ausnahmen (z.B. System.DivideByZeroException und System.OverflowException ), die während arithmetischer Operationen auftreten. |
System.ArrayTypeMismatchException |
Wird ausgelöst, wenn ein Speicher in einem Array fehlschlägt, da der Typ des gespeicherten Elements nicht mit dem Typ des Arrays kompatibel ist. |
System.DivideByZeroException |
Wird ausgelöst, wenn versucht wird, einen integralen Wert durch Null zu dividieren. |
System.IndexOutOfRangeException |
Wird ausgelöst, wenn versucht wird, ein Array über einen Index zu indizieren, der kleiner als Null oder außerhalb der Grenzen des Arrays ist. |
System.InvalidCastException |
Wird ausgelöst, wenn zur Laufzeit eine explizite Konvertierung von einem Basistyp oder einer Schnittstelle zu einem abgeleiteten Typ fehlschlägt. |
System.NullReferenceException |
Wird ausgelöst, wenn ein null Verweis auf eine Weise verwendet wird, die dazu führt, dass das referenzierte Objekt erforderlich ist. |
System.OutOfMemoryException |
Wird ausgelöst, wenn beim Versuch, Speicher zuzuweisen (via new ) fehlschlägt. |
System.OverflowException |
Wird ausgelöst, wenn eine arithmetische Operation im Kontext checked überläuft. |
System.StackOverflowException |
Wird ausgelöst, wenn der Ausführungsstapel durch zu viele ausstehende Aufrufe erschöpft ist; in der Regel bezeichnend für eine sehr tiefe oder ungebundene Rekursion. |
System.TypeInitializationException |
Wird ausgelöst, wenn ein statischer Konstruktor oder ein statischer Feldinitialisierer eine Ausnahme auslöst und keine catch Klausel vorhanden ist, um ihn abzufangen. |
ECMA C# draft specification