HIK Elektronikus Felsőoktatási Tankönyv- és Szakkönyvtár
A Kempelen Farkas Felsőoktatási Digitális Tankönyvtár/vagy más megjelenítő által közvetített digitális tartalmat a felhasználó a szerzői jogról szóló 1999. évi LXXVI. tv. 33. paragrafus (4) bekezdésében meghatározott oktatási, illetve tudományos kutatási célra használhatja fel. A felhasználó a digitális tartalmat képernyőn megjelenítheti, letöltheti, arról elektronikus adathordozóra vagy papíralapon másolatot készíthet, adatrögzítő rendszerében tárolhatja. A Kempelen Farkas Felsőoktatási Digitális Tankönyvtár/vagy más megjelenítő weblapján található digitális tartalmak üzletszerû felhasználása tilos, valamint kizárt a digitális tartalom módosítása és átdolgozása, illetve az ilyen módon keletkezett származékos anyag további felhasználása.

16.2.1. A try és a catch

A try parancs segítségével a programok egyes részeihez hibakezelő rutinokat rendelhetünk, melyek hiba esetén az általunk megírt hibakezelő eljárásokat hajtják végre, s ami nagyon fontos, megakadályozzák a program leállását.

A catch segítségével azokat a kivételeket kaphatjuk el, melyek a try blokkban keletkeznek. Itt határozhatjuk meg, hogy milyen rutinok fussanak le és hogyan kezeljék a felmerülő hibákat. A catch segítségével különböző hibák egyidejű kezelését is megvalósíthatjuk, de erről majd bővebben szólunk a fejezet későbbi részeiben. Most nézzünk meg egy példát a try használatára!

using System;

namespace ConsoleApplication6

{

class Class1

{

[STAThread]

static void Main(string[] args)

{

string s;

int i;

Console.WriteLine("Kérem gépeljen be egy tetszőleges

mondatot!");

s=Console.ReadLine();

try

{

for (i=0;i<20;i++)

{

Console.WriteLine("Az s string {0}. eleme =

{1}",i,s[i]);

}

}

catch

{

Console.WriteLine("Hiba a program futása során...");

}

Console.ReadLine();

}

}

}

Amennyiben futtatjuk a fenti programot, és a beolvasásnál 20 karakternél rövidebb mondatot adunk meg, a hibakezelő eljárás elindul, mivel a try a catch blokkhoz irányítja a vezérlést. A catch blokkban definiált hibakezelő rész lefut, vagyis a képernyőn megjelenik a hibaüzenet.

Abban az esetben, ha nem használjuk a hibakezelő eljárásokat, a programunk leáll, és a hiba kezelését a .NET vagy az operációs rendszer veszi át. Ebből a példából is jól látható milyen nagy szükség lehet a kivételkezelőre, ha jól működő programokat akarunk írni. Fokozottan érvényes ez azokra a programokra, ahol a felhasználó adatokat visz be.

A következő programban erre láthatunk példát. Amennyiben az inputról nem megfelelő adatok érkeznek, működésbe lép a kivétel-kezelés, a catch blokkban elkapjuk a hibát és kiírjuk az okát a képernyőre.

using System;

namespace ConsoleApplication4

{

class Class1

{

[STAThread]

static void Main(string[] args)

{

int i;

try

{

Console.WriteLine("Az i értéke? : ");

i=Convert.ToInt32(Console.ReadLine());

}

catch(Exception e){Console.WriteLine(e.Message);}

Console.ReadLine();

}

}

}

A programban látható, hogy a try után kapcsos zárójelek közt adjuk meg a hibát okozható program részletet. A catch hibakezelő rutinjait szintén kapcsos zárójelek közé kell írni, ezzel jelezve a fordítónak, hogy hol kezdődik és végződik a hibakezelés.

A fenti példában a túlindexelés és a típus különbségek mellett előfordulhatnak más hibák is, melyek a program írásakor rejtve maradnak. Az ilyen jellegű hibákra az előző kód nincs felkészítve, mivel nem definiáltuk a lehetséges hibákat. Ez azt jelenti, hogy a try blokkban előforduló bármely hiba esetén ugyanaz a hibaüzenet jelenik meg a képernyőn.

A catch blokkban lehetőségünk van a különböző okok miatt keletkezett hibák szétválasztására, a hiba típusának meghatározására.

A catch parancs a kivételt paraméterként is fogadhatja, ahogy a fenti példában láthattuk. A paraméterként megadott változó System.Exception típusú, melyből kiolvashatjuk a hiba okát, amit az e.Message rutinnal kapunk meg, és a megfelelő hibakezelőt indíthatjuk el.

catch ( System.Exception e )

{

Console.WriteLine(e.Message);

//hibák kezelése

}

A képernyőn megjelenő hibaüzenet nem nagyon beszédes, illetve gyakran túlságosan sok, nehezen érthető információt tartalmaz. A célunk sem az, hogy a programunk használóját hosszú, értelmezhetetlen üzenetekkel terheljük, mert így nem teszünk többet, mint az eredeti hiba-ablak. Ráadásul a felhasználó nem is nagyon tudja kezelni a keletkezett hibákat, még annak ellenére sem, hogy kiírjuk a képernyőre a hiba minden paraméterét.

Sokkal jobb megoldás, ha megállapítjuk a hiba okát, majd a megfelelő hibakezelés aktivizálásával meg is szüntetjük azt. (Ekkor még mindig ráérünk kiírni a képernyőre, hogy hiba történt, és a javított hibáért a felhasználó nem is haragszik annyira… Talán még elismerően bólint is…)

Írhatunk olyan catch blokkokat is, melyek egy bizonyos típusú hiba elfogására alkalmasak.

int a=0;

double c;

try

{

c = 10 / a + 30;

}

catch (ArithmeticException ar)

{

Console.WriteLine("Aritmetikai hiba : {0}",ar);

}

A catch blokkok sorrendje sem mindegy. A helyes megközelítés az, ha az általános hibák elé helyezzük azokat a hibákat, melyekre már eleve számítani lehet a programban, mint pl.: a fenti matematikai hiba.

A System névtérben rengeteg kivétel típust definiáltak. A fontosabbakat az alábbi táblázatban foglaltuk össze.

Kivétel neve

Leírása

MemberAccesException

Tagfüggvény hozzáférési hiba

ArgumentException

Hibás tagfüggvény-paraméter

ArgumentNullException

Null értékű tagfüggvény paraméter

ArithmeticException

Matematikai művelet-hiba

ArrayTypeMismatchException

Tömbtípus hibája (érték tároláskor)

DivideByZeroException

Nullával való osztás

FormatException

Hibás paraméter-formátum

IndexOutOfRangeException

Tömb túl, vagy alulindexelése

InvalidCastException

Érvénytelen típus átalakítás

NotFiniteNumberException

A keletkezet érték nem véges (hibás számalak)

NullReferenceException

Null értékre való hivatkozás

NotSupportedException

Nem támogatott tagfüggvény

OutOfMemoryException

Elfogyott a memória

OverflowException

Túlcsordulás (checked esetén)

StackOverflowException

Verem túlcsordulás

TypeInitializationException

Hibás típus beállíás (static kontruktornál)