21 Uitzonderingen
21.1 Algemeen
Uitzonderingen in C# bieden een gestructureerde, uniforme en typeveilige manier om foutvoorwaarden op systeemniveau en toepassingsniveau te verwerken.
21.2 Oorzaken van uitzonderingen
Uitzonderingen kunnen op twee verschillende manieren worden gegenereerd.
- Een
throw
verklaring (§13.10.6) genereert onmiddellijk en onvoorwaardelijke uitzondering. Control bereikt de instructie nooit onmiddellijk na dethrow
. - Bepaalde uitzonderlijke omstandigheden die zich voordoen tijdens de verwerking van C#-instructies en -expressies zorgen ervoor dat een uitzondering in bepaalde omstandigheden wordt gegenereerd wanneer de bewerking niet normaal kan worden voltooid. Zie §21.5 voor een lijst met de verschillende uitzonderingen die op deze manier kunnen worden gegenereerd.
Voorbeeld: Een deelbewerking voor gehele getallen (§12.10.3) genereert een
System.DivideByZeroException
als de noemer nul is. eindvoorbeeld
21.3 De klasse System.Exception
De System.Exception
klasse is het basistype van alle uitzonderingen. Deze klasse heeft enkele belangrijke eigenschappen die alle uitzonderingen delen:
Message
is een alleen-lezen eigenschap van het typestring
dat een door mensen leesbare beschrijving van de reden voor de uitzondering bevat.InnerException
is een alleen-lezen eigenschap van het typeException
. Als de waarde niet isnull
, verwijst deze naar de uitzondering die de huidige uitzondering heeft veroorzaakt. (Dat wil gezegd, de huidige uitzondering is gegenereerd in een catch block handling deInnerException
.) Anders is de waarde,null
waarmee wordt aangegeven dat deze uitzondering niet is veroorzaakt door een andere uitzondering. Het aantal uitzonderingsobjecten dat op deze manier is gekoppeld, kan willekeurig zijn.
De waarde van deze eigenschappen kan worden opgegeven in aanroepen naar de instantieconstructor voor System.Exception
.
21.4 Hoe uitzonderingen worden verwerkt
Uitzonderingen worden verwerkt door een try
instructie (§13.11).
Wanneer er een uitzondering wordt gegenereerd (§21.2), zoekt het systeem naar de dichtstbijzijnde catch-component die de uitzondering kan verwerken, zoals wordt bepaald door het uitvoeringstype van de uitzondering. Eerst wordt de huidige methode gezocht naar een lexicale insluitingsinstructie try
en worden de bijbehorende catch
componenten van de try
instructie in volgorde beschouwd. Als dat mislukt, wordt de methode die de huidige methode wordt genoemd, gezocht naar een lexische insluitingsinstructie try
die het punt van de aanroep naar de huidige methode omsluit. Deze zoekopdracht wordt voortgezet totdat een catch
component wordt gevonden die de huidige uitzondering kan verwerken, door een uitzonderingsklasse te benoemen die van dezelfde klasse of een basisklasse is, van het runtimetype van de uitzondering die wordt gegenereerd. Een catch
component die geen naam geeft aan een uitzonderingsklasse, kan elke uitzondering verwerken.
Zodra een overeenkomende catch
component is gevonden, bereidt het systeem zich voor om het besturingselement over te dragen naar de eerste instructie van de catch
component. Voordat de uitvoering van de catch
component begint, voert het systeem eerst eventuele finally
componenten uit die zijn gekoppeld aan try
instructies die meer genest zijn dan degene die de uitzondering heeft onderschept.
Als er geen overeenkomende catch
component wordt gevonden:
- Als de zoekopdracht naar een overeenkomende
catch
component een statische constructor (§15.12) of statische veld-initialisatie bereikt, wordt er eenSystem.TypeInitializationException
gegenereerd op het punt dat de aanroep van de statische constructor heeft geactiveerd. De binnenste uitzondering van deSystem.TypeInitializationException
bevat de uitzondering die oorspronkelijk is gegenereerd. - Als er anders een uitzondering optreedt tijdens de uitvoering van de finalizer en deze uitzondering niet wordt opgevangen, wordt het gedrag niet opgegeven.
- Als de zoekopdracht naar overeenkomende
catch
componenten de code bereikt die de thread aanvankelijk heeft gestart, wordt de uitvoering van de thread beëindigd. De impact van deze beëindiging is gedefinieerd door de implementatie.
21.5 Algemene uitzonderingsklassen
De volgende uitzonderingen worden gegenereerd door bepaalde C#-bewerkingen.
Uitzonderingstype | Beschrijving |
---|---|
System.ArithmeticException |
Een basisklasse voor uitzonderingen die optreden tijdens rekenkundige bewerkingen, zoals System.DivideByZeroException en System.OverflowException . |
System.ArrayTypeMismatchException |
Gegenereerd wanneer een archief in een matrix mislukt omdat het type van het opgeslagen element niet compatibel is met het type matrix. |
System.DivideByZeroException |
Gegenereerd wanneer een poging om een integrale waarde door nul te delen plaatsvindt. |
System.IndexOutOfRangeException |
Gegenereerd wanneer een poging om een matrix te indexeren via een index die kleiner is dan nul of buiten de grenzen van de matrix valt. |
System.InvalidCastException |
Gegenereerd wanneer een expliciete conversie van een basistype of interface naar een afgeleid type mislukt tijdens runtime. |
System.NullReferenceException |
Gegenereerd wanneer een null verwijzing wordt gebruikt op een manier die ervoor zorgt dat het object waarnaar wordt verwezen, vereist is. |
System.OutOfMemoryException |
Gegenereerd wanneer een poging om geheugen toe te wijzen (via new ) mislukt. |
System.OverflowException |
Gegenereerd wanneer een rekenkundige bewerking in een checked context overloopt. |
System.StackOverflowException |
Gegenereerd wanneer de uitvoeringsstack is uitgeput door te veel in behandeling zijnde aanroepen; meestal indicatief voor zeer diepe of niet-gebonden recursie. |
System.TypeInitializationException |
Gegenereerd wanneer een statische constructor of statische veld initialisatiefunctie een uitzondering genereert en er geen catch component bestaat om deze te vangen. |
ECMA C# draft specification