Delen via


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 de throw.
  • 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 type string dat een door mensen leesbare beschrijving van de reden voor de uitzondering bevat.
  • InnerException is een alleen-lezen eigenschap van het type Exception. 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 de InnerException.) Anders is de waarde, nullwaarmee 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 een System.TypeInitializationException gegenereerd op het punt dat de aanroep van de statische constructor heeft geactiveerd. De binnenste uitzondering van de System.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.