Krizsán Zoltán 1 1/29 Kivétel kezelés Krizsán Zoltán 1 Általános Informatikai Tanszék Miskolci Egyetem Objektumorientált programozás C# alapokon tananyag
Krizsán Zoltán 1 2/29 Tartalom 1 Kivétel kezelés Általános információk Kivétel (Exception) Kivétel kezelés Saját kivétel osztály készítése
Krizsán Zoltán 1 3/29 A kivételkezelés célja Kivételes helyzetek (hibák) a jól megírt programokban is el fordulnak. Például: er forrás hiány (lemez megtelt), valamilyen funkció hiányos vagy hibás adatok miatt nem hajtható végre Ezeket a szituációkat kezelni kell. A szükséges teend k elvégzése után általában a program folytatni tudja a munkát.
Krizsán Zoltán 1 4/29 Hagyományos hibakezelés Függvény visszatérési értéke (paramétere) hátrányai: azonosítás hibaérték / valódi érték megkülönböztetése nehézkes hívási hierarchia! Ellen rzés nehézkes, sok helyre kell beiktatni. Kód áttekinthet ségét rontja! A funkcionális és a hibakezel kódrészletek keverednek.
Krizsán Zoltán 1 5/29 Tartalom 1 Kivétel kezelés Általános információk Kivétel (Exception) Kivétel kezelés Saját kivétel osztály készítése
Krizsán Zoltán 1 6/29 Kivétel - exception Futás idej hiba / nem normális eset. Általában valamilyen hibához köt dik. Számos beépített kivétel. Saját kivétel deniálható. A C# szemléletében a kivétel egy objektum, ami a kivétel bekövetkezésekor jön létre. Saját (programozói) kivétel kiváltása: throw objektum
Krizsán Zoltán 1 7/29 Kivétel - hiba I A kivétel keletkezésekor szokásos teend k: értesíteni a felhasználót, vagy naplózni, majd valamilyen plusz m veletek után folytatni az alkalmazást, esetleg kilépni, súlyos hiba esetén. Ellen rzött kilépés lehetséges. (Például el tte minden értékes adat elmenthet.) A kivétel objektum tartalmazhat információkat a kivétel keletkezésér l, amelyet felhasználhatunk.
Krizsán Zoltán 1 8/29 Tartalom 1 Kivétel kezelés Általános információk Kivétel (Exception) Kivétel kezelés Saját kivétel osztály készítése
Krizsán Zoltán 1 9/29 Kivételkezelés utasításai I try védett kód (blokk) kijelölése throw kivétel dobása, generálása catch kivétel elkapása, a blokkban deniált utasítások végrehajtása nally végül, akár volt kivétel, akár nem volt, lefut
Krizsán Zoltán 1 10/29 try blokk I A védett kódot try blokkban helyezzük el: try { utasítások } A blokkban keletkezett kivételt mi kezelhetjük le. A blokkok egymásba ágyazhatóak. Érdemes minél kisebb blokkokat deniálni. Kivétel keletkezik, ha a try blokkban egy throw utasításra fut a vezérlés. Formája: throw new kivételtípus(konstruktor paraméterek) A throw paramétere nem maradhat el!
Krizsán Zoltán 1 11/29 Kivétel keletkezése I Kivétel keletkezhet az alábbi módokon: Implicit módon: a C# rendszerb l indul ki, azaz valamely utasítás vagy API elem végrehajtása során keletkezik. A programozó kódjában keletkezik, közvetlenül egy throw utasítás végrehajtásával. Aszinkron kivétel, amely a program egy másik szálán lépett fel. A kivétel keletkezése esetén: Az els kivételt kiváltó utasítással befejez dik a try blokk végrehajtása. Kilép a blokkból a vezérlés, rendcsinálással verem visszaállítása, lokális objektumok megszüntetése, védett változók lezárásának megszüntetése. Létrejön a throw utasításban megjelölt objektum egy példánya.
Krizsán Zoltán 1 12/29 Kivétel elkapása I A kivétel objektumot minden esetben a rendszer hozza létre. A kivétel lekezelését szolgáló utasítások catch blok(kok)ban helyezkednek el. Formája: catch (típus paraméter) {utasítások} A catch minden esetben a try blokkot követi, nem lehet köztük más utasítás. Egy try blokkhoz tartozhat több catch is. A rendszer megkeresi a sorrendben els "illeszked " blokkot, és annak végrehajtásával folytatódik a program. Az illeszkedés feltétele: a kivétel objektum típusa megegyezik a catch blokk fejében megadott típussal, vagy annak leszármazottja.
Krizsán Zoltán 1 13/29 Kivétel elkapása II A kiválasztott blokk végrehajtása során a paramétere úgy használható, mint a függvények esetén a formális paraméter. Így lehet felhasználni a kivétel objektumban tárolt információkat. A futás az utolsó catch utáni sorral folytatódik. Ha ha a catch blokk végrehajtása során újabb kivétel keletkezik, az eredeti kivétel kezelése megszakad, és az új kivétel lekezelése kezd dik el. Ha egyetlen catch blokk sem illeszkedett a kivételre, a keresés a beágyazó try blokk catch blokkjaival folytatódik, amíg sikeres nem lesz. Ha a keresés belülr l kifelé minden try blokkot megvizsgált, és nem talált egyezést, a program terminálódik, és kiíródik a kivétel stack. (Lekezeletlen kivétel.)
Krizsán Zoltán 1 14/29 Kivétel elkapása III Megjegyzés: a try blokk kivételt kiváltó utasítása utáni utasítások tehát mindig kimaradnak!
Krizsán Zoltán 1 15/29 nally blokk I Nem kötelez. A cacth(ek) után szerepelhet. Az utolsó catch blokk és a nally blokk között nem lehet más utasítás. Nem lehet paramétere. Minden esetben lefut. Ha kivétel keletkezett a try blokkban, egy catch blokk végrehajtása után. Ha nem volt kivétel, a try blokk utolsó utasítása után. Alkalmas például fájlok, adatbázis kapcsolatok lezárására.
Krizsán Zoltán 1 16/29 Egymásba ágyazott try blokkok I A try blokkok egymásba ágyazhatók közvetlenül, vagy közvetve, amikor a try blokkban egy olyan metódus hívása szerepel, amely tartalmaz try blokkot. Úgy tekinthetjük, hogy a main metódus egy implicit try blokkban fut, és itt kezel dik le minden olyan kivétel, amelyet egyetlen catch blokk sem kapott el el tte.
Krizsán Zoltán 1 17/29 Kivétel kezelés egyszer feladat I Készítsünk alkalmazást, amelyben bekérünk egy számot majd írjuk ki a kétszeresét! Egyszer nek t nik, de Nem lehet számot bekérni = szöveget kérünk, konvertálni kell. Mi van, ha a felhasználó nem ad meg számot (üres enter)? Mi van, ha megad szöveget, de az nem szám (pl.: 123fecc)?
Krizsán Zoltán 1 18/29 Kivétel kezelés példa I 1 try { 2 String str ; 3 Int32 szam ; 4 5 str = Console. ReadLine () ; 6 7 if ( str. Length == 0) { 8 throw new ApplicationException ("A szoveg ures!"); 9 } 10 11 szam = Convert. ToInt16 ( str ); 12 Console. WriteLine (" {0} ", szam * 2) ; 13 }
Krizsán Zoltán 1 19/29 Kivétel kezelés példa II 14 catch ( System. ApplicationException ex ){ 15 System. Console. WriteLine (" Ures a szoveg "); 16 } 17 catch ( FormatException ex ){ 18 System. Console. WriteLine (" Rossz formatum "); 19 } 20 catch ( System. Exception ex ){ 21 System. Console. WriteLine ( ex. ToString () ); 22 } 23 System. Console. WriteLine (" Done ");
Krizsán Zoltán 1 20/29 Hogyan m ködhet? I Ha minden jól m ködik: futott sorok: 1-7, 11, 12, 23 Convert.Toint16 : konvertálás szövegr l számra FormatException : ha a beolvasott szöveg nem alakítható számmá. futott sorok: 1-7, 11, 17, 18, 23 OverowException : ha a szöveg konvertálható lenne ugyan számmá, de az túl nagy, vagy kicsi (pl.: 45000) futott sorok: 1-7, 11, 17, 18, 23 throw : ha str.length() == 0 ApplicationException : ha üres a bekért szöveg futott sorok: 1-7, 8, 14, 15, 23
Krizsán Zoltán 1 21/29 Exception osztály I Lehet leg, remélhet leg minden kivétel közvetett, vagy közvetlen se. Fontosabb elemei: StackTrace : a kivételek láncolatát érhetjük el InnerException : a következ kivétel a láncban (kiváltó) Message : kivétel szövege Data : kivételhez kapcsolt információ
Krizsán Zoltán 1 22/29 Kivétel továbbdobása ROSSZ MEGOLDÁS I Törli a kivétel stack-et. 1 try { 2 // code here 3 } 4 catch ( Exception ex ){ 5 // some code here related to the exception 6 throw ex ; // Reset the StackTrace to make finding the real problem harder to find 7 }
Krizsán Zoltán 1 23/29 Kivétel továbbdobása JÓ MEGOLDÁS I 1 try { 2 // code here 3 } 4 catch ( Exception ex ){ 5 // some code here related to the exception 6 throw ; // Notice the absence of the ex expression 7 }
Krizsán Zoltán 1 24/29 Kivétel továbbdobása JÓ MEGOLDÁS II I jobb, mert + információkat lehet felf zni, debug-golható. 1 try 2 { 3 } 4 catch ( Exception ex ) 5 { 6 throw new Exception (" Put more context here ", ex ) 7 }
Krizsán Zoltán 1 25/29 Tartalom 1 Kivétel kezelés Általános információk Kivétel (Exception) Kivétel kezelés Saját kivétel osztály készítése
Krizsán Zoltán 1 26/29 Kivételek fajtái I Program által kiváltott. ApplicationException Keretrendszer (CLI) által kiváltott. SystemException
Krizsán Zoltán 1 27/29 Gyakori kivételek I IndexOutOfRangeException: ha túl indexeltük a tömböt. 1 arr [ arr. Length +1] NullReferenceException: ha valahol null objektumon keresztül probáltak elemekhez hozzáférni. 1 object o = null ; 2 o. ToString () ; ArgumentNullException: ha valamely metódus null paramétert kapott 1 String s = null ; 2 " Calculate ". IndexOf (s);
Krizsán Zoltán 1 28/29 Saját kivétel osztály készítése I Az osztály neve legyen Exception vég. Pl.: GepElromlottException. Žsosztály az Exception vagy ApplicatinoException legyen. Tegyük sorosíthatóvá ([Serializable]) Készítsünk 3 konstruktort: paraméter nélkülit 1 paraméterest, amely a hiba szövegét kapja meg (Message tulajdonság). 2 paraméterest, hiba szövegét és a bels kivételt kapja meg.
Krizsán Zoltán 1 29/29 Saját kivétel példa I 1 [ Serializable ] 2 public class G epel roml otte xcep tion : Exception 3 { 4 public GepElromlottException () 5 { 6 } 7 public G epel roml otte xcep tion ( string message ) 8 : base ( message ) 9 { 10 } 11 public G epel roml otte xcep tion ( string message, Exception inner ) 12 : base ( message, inner ) 13 { 14 } 15 }