21 Undantag
21.1 Allmänt
Undantag i C# ger ett strukturerat, enhetligt och typsäkert sätt att hantera både feltillstånd på systemnivå och programnivå.
21.2 Orsaker till undantag
Undantag kan genereras på två olika sätt.
- Ett
throw
meddelande (§13.10.6) kastar ett undantag omgående och ovillkorligt. Kontrollen når aldrig -instruktionen omedelbart efterthrow
. - Vissa exceptionella villkor som uppstår under bearbetningen av C#-instruktioner och uttryck gör att ett undantag utlöses under vissa omständigheter när åtgärden inte kan slutföras normalt. Se §21.5 för en lista över de olika undantag som kan kastas på detta sätt.
Exempel: En heltalsdivisionsåtgärd (§12.10.3) utlöser en
System.DivideByZeroException
om nämnaren är noll. slutexempel
21.3 Klassen System.Exception
Klassen System.Exception
är bastypen för alla undantag. Den här klassen har några viktiga egenskaper som alla undantag delar:
Message
är en skrivskyddad egenskap av typenstring
som innehåller en läsbar beskrivning av orsaken till undantaget.InnerException
är en skrivskyddad egenskap av typenException
. Om dess värde intenull
är refererar det till undantaget som orsakade det aktuella undantaget. (Det vill: det aktuella undantaget uppstod i ett catch block-hantering avInnerException
.) Annars ärnull
dess värde , vilket indikerar att det här undantaget inte orsakades av ett annat undantag. Antalet undantagsobjekt som är sammanlänkade på det här sättet kan vara godtyckligt.
Värdet för dessa egenskaper kan anges i anrop till instanskonstruktorn för System.Exception
.
21.4 Så här hanteras undantag
Undantag hanteras av en try
instruktion (§13.11).
När ett undantag utlöses (§21.2) söker systemet efter den närmaste catch-satsen som kan hantera undantaget, enligt undantagets körningstyp. För det första söks den aktuella metoden efter en lexikal omslutande try
instruktion, och de associerade catch
satserna i -instruktionen try
beaktas i ordning. Om det misslyckas söks den metod som anropade den aktuella metoden efter en lexikal omslutande try
instruktion som omger anropets punkt till den aktuella metoden. Den här sökningen fortsätter tills en catch
sats hittas som kan hantera det aktuella undantaget genom att namnge en undantagsklass som är av samma klass, eller en basklass, av körningstypen för undantaget som genereras. En catch
sats som inte namnger en undantagsklass kan hantera alla undantag.
När en matchande catch
sats hittas förbereder systemet att överföra kontrollen till den första instruktionen i catch
-satsen. Innan körningen catch
av satsen börjar kör systemet först i ordning alla finally
satser som var associerade med try
uttryck som är mer kapslade än de som fångade undantaget.
Om ingen matchande catch
sats hittas:
- Om sökningen efter en matchande
catch
sats når en statisk konstruktor (§15.12) eller statisk fältinitierare genereras enSystem.TypeInitializationException
vid den punkt som utlöste anropet av den statiska konstruktorn. Det inre undantaget förSystem.TypeInitializationException
innehåller undantaget som ursprungligen utlöstes. - Om ett undantag inträffar under slutförandekörningen och undantaget inte fångas är beteendet annars ospecificerat.
- Annars avslutas körningen av tråden om sökningen efter matchande
catch
satser når den kod som ursprungligen startade tråden. Effekten av en sådan uppsägning är implementeringsdefinierad.
21.5 Vanliga undantagsklasser
Följande undantag utlöses av vissa C#-åtgärder.
Undantagstyp | Beskrivning |
---|---|
System.ArithmeticException |
En basklass för undantag som inträffar under aritmetiska åtgärder, till exempel System.DivideByZeroException och System.OverflowException . |
System.ArrayTypeMismatchException |
Utlöses när ett lager i en matris misslyckas eftersom typen av det lagrade elementet inte är kompatibel med typen av matris. |
System.DivideByZeroException |
Utlöses när ett försök att dividera ett integralvärde med noll inträffar. |
System.IndexOutOfRangeException |
Utlöses när ett försök att indexeras en matris via ett index som är mindre än noll eller utanför matrisens gränser. |
System.InvalidCastException |
Utlöses när en explicit konvertering från en bastyp eller ett gränssnitt till en härledd typ misslyckas vid körning. |
System.NullReferenceException |
Genereras när en null referens används på ett sätt som gör att det refererade objektet krävs. |
System.OutOfMemoryException |
Utlöses när ett försök att allokera minne (via new ) misslyckas. |
System.OverflowException |
Utlöses när en aritmetikåtgärd i en checked kontext flödar över. |
System.StackOverflowException |
Utlöses när körningsstacken är slut genom att ha för många väntande anrop. tyder vanligtvis på mycket djup eller obundna rekursioner. |
System.TypeInitializationException |
Utlöses när en statisk konstruktor eller statisk fältinitierare utlöser ett undantag och det inte finns någon sats catch för att fånga den. |
ECMA C# draft specification