Freigeben über


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 der throw.
  • 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 Typs string , die eine lesbare Beschreibung des Grunds für die Ausnahme enthält.
  • InnerException ist eine schreibgeschützte Eigenschaft vom Typ Exception. 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 die InnerException.) Andernfalls lautet nullder 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 an System.TypeInitializationException der Stelle ausgelöst, an der der Aufruf des statischen Konstruktors ausgelöst wurde. Die innere Ausnahme der System.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.