A C# kivétel-kezelési módszere a try-catch-throw-finally vonalat követi. A C++-ban
illetve Java-ban megszokott kivételkezelést használhatjuk: A try {…} blokkon belül
fellépő hibát neki megfelelő catch() {..} blokk kapja
el. Ha van finally tag, akkor az mind normál, mind kivétel esetén lefut. Manuálisan
kivételt dobni a throw() utasítással lehet. Használható
finally szakasz is egy kivételkezelő blokkban. Ennek szemantikája a Java-nak megfelelő.
Vannak előredefiniált kivételek a rendszer eseményeinek kezelésére: System.OutOfMemoryException,
System.DivideByZeroException stb
try
{ //esetleges hibák }
catch( típus [név] )
{ //egy vezérlési ág egy bizonyos hiba esetén }
..
finally
{ ..//biztosan lefut, hibától függetlenül}
Néhány fontos különbség azonban van az említett nyelvekhez képest:
Míg C++-ban minden típus lehet kivételtípus, addig C#-ban minden kivételtípus a
System.Exception ősosztályból kell származzon.
A throw utasítással lehet kiváltani kivételt, például:
if(Price == -1) { throw new Exception{} }
Ha nem jó nekünk az általános Exception osztály, adjuk meg annak leszármazottját, akár egy saját kivételosztályt.
A catch blokk maga a kivételkezelő rész. Ha a try blokkban kivétel
keletkezik, azonnal ide kerül a vezérlés.
Több catch blokk is állhat a try blokk után. Ennek azért van értelme, mert minden
catch blokk adott típusú kivételt tud kezelni, olyanokat, melyek típusa kompatibilis
a catch fejében megadott kivételtípussal.
Ha nem adunk meg kivételt, akkor minden kivételtípust el fog kapni a catch, mivel
ez megegyezik azzal, mintha a kivételek ősosztályát, a System.Exceptiont adtuk volna
meg:
Konkretizálva a
változattal.
A catch fejrészében nem kötelező a típus mellett az azonosítót is megadni, ha nem
akarjuk az azonosítóval megjelölt kivétel példányt felhasználni az azonosítón keresztül.
A fordító szól is, ha deklaráltuk, de nem használtuk.
Ez szabályos kódváz.
A finally blokk arra való, hogy olyan utasításokat helyezzünk el benne, melyeket attól függetlenül le akarunk futtatni, hogy történik-e kivétel, vagy sem. Ilyenek lehetnek a lefoglalt erőforrások felszabadítását elvégző utasítások (fájl referencia felszabadítása, hálózati kapcsolat bezárása stb.).
Ha kivétel keletkezik, és azt lekezeljük, akkor rögtön a kivétel lekezelése után a finally blokkra ugrik a vezérlés. Ha nincs lekezelve a kivétel, akkor mielőtt a kivétel továbbterjed, lefut a finally blokk.
Ha egy kivételt nem kezelünk le, mert nincs try-catch blokk, vagy van ugyan, de nincs felsorolva a catch mögött a dobott kivétel osztálya, vagy annál bővebb osztály, akkor a kivétel továbbterjed az aktuális függvényt hívó függvény szintjére. Ha a kivétel felgyűrűzik a main függvényig, és ott sincs lekezelve, akkor futásiidejű hibaként továbbadódik az operációs rendszernek, ami kiírja a megfelelő hibaüzenetet.