A C# programozási nyelv

Kivételkezelés

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

Szintaxis

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}

Kivételek definiálása

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.

Kivételek kiváltása

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.

Kivételek kezelése

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

try {}
catch (Exception azonosító)
{
}
forma ekvivalens a
try {}
catch
{
}

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.

try {}
catch (Exception)
{
}

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.

Kivételek terjedése

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.