Programmeren in C# Exceptions Hoofdstuk 17
In dit hoofdstuk Wat is een exception? Waarom zijn ze nuttig? De C# exception faciliteiten. Programmeren in C# 2
Overzicht Inleiding Try-Catch Combinatie Catch blokken Opgooien van exceptie Finally Zelf exceptie schrijven Programmeren in C# 3
Programmeren in C# 4 Syntaxfouten Soorten fouten (1) Bekijk je fouten in de Error List
Programmeren in C# 5 Soorten fouten (2) Logische fouten Programma produceert foute resultaten Niet altijd een crash tot gevolg! Bv: oneindige lussen Enkel op te lossen door uitvoerig te testen Run-time fouten een onmogelijke operatie Niet gedetecteerd door de compiler Bv: deling door nul
Exceptie Exception à er is een fout opgetreden Exception handling à afhandelen van de fout op een gecontroleerde manier Voorbeelden: Ongeldige invoer (bv. een letter i.p.v. een getal) Netwerkproblemen (bv. DNS fout) Schijfproblemen (bv. bestand niet gevonden) Hardwareproblemen (bv. geen papier in printer) Programmeren in C# 6
Programmeren in C# 7 Problemen afhandelen Ongeldige invoer (bv. een letter i.p.v. getal) Netwerkproblemen (bv. DNS fout) Schijfproblemen (bv. bestand niet gevonden) Stoppen van programma zou stom zijn Gebruiker op hoogte brengen van probleem en hem nieuwe mogelijkheid bieden Hardwareproblemen (bv. geen papier in printer) Gebruiker op hoogte brengen van probleem Opties bieden om afdrukopdracht te verlaten of activiteit voor te zetten indien papier is aangevuld
Verschillende fouttypes en verschillende plaatsen voor afhandeling Complexe systemen hebben hiërarchie van methoden (methoden roepen anderen aan) Sommige problemen kunnen lokaal (in methode zelf) afgehandeld worden, anderen misschien doorgegeven worden op hogere niveaus Afh. van type fout K1 functie1() K2 functie2() K3 functie3() Verschillende fouttypes en afhandeling op verschillende plaatsen Programmeren in C# 8
Programmeren in C# 9 Analogie Organisatie Orders door hiërarchie. Bij fouten Directeur Order Manager Order Papier in printer is op. Technicus lost dit op. In zeldzame geval geen papier in organisatie, dan manager Technicus struikelt over kabel en breekt been. Afhandeling door directeur door juridische kwesties Technici
Programmeren in C# 10 Ideale wereld Voorstelling programma met een normale werking. Als er nooit fouten zouden optreden is dit correct: MethodeA(); MethodeB(); MethodeC();
Programmeren in C# 11 Werkelijkheid MethodeA(); if (MethodeA misliep) // handel het methodea-probleem af else MethodeB(); if (methodeb misliep) // handel het methodeb-probleem af else MethodeC(); if (methodec misliep) // handel het methodec-probleem af Oude manier Ingewikkeld Niet overzichtelijk
17.2, p320 Hoe kan methode retourneren dat het goed verlopen is of niet? Is dit altijd mogelijk? Programmeren in C# 12
Jargon Als een fout zich voordoet in het programma: Wordt er door de runtime omgeving of door de methode zelf een speciaal object aangemaakt Men zegt dat een exceptionopgegooid wordt (Engels: to throw) Hoe afhandelen: Op de gepaste locatie (bij aanroep van methode die exception heeft opgegooid) kan men deze exception opvangen (dus niet altijd vlak erna met een if) (Engels: to catch) Sleutelwoorden: throw, try, catch, finally F2= Functie die F1 oproept try F1() catch finally F1= Functie met mogelijke problemen Throw Exception Programmeren in C# 13
Programmeren in C# 14 Terminologie visueel F2= Functie die F1 oproept try F1() catch finally F1= Functie met mogelijke problemen Throw Exception Exception klasse
Overzicht Inleiding Try-Catch Combinatie Catch blokken Opgooien van exceptie Finally Zelf exceptie schrijven Programmeren in C# 15
Typ in en wat krijg je? double a = Double.Parse("blabla"); double a = Convert.ToDouble("blabla"); F2= Functie die F1 oproept try F1() catch F1= Functie met mogelijke problemen Throw Exception Programmeren in C# 16
Programmeren in C# 17 Een try-catch voorbeeld Demo Exception Square
Een try-catch voorbeeld private void button_click(object sender, EventArgs e) double side; try side = Double.Parse(textBox.Text); label.content = String.Format("Area is 0 square units.", (side * side)); catch (FormatException exceptionobject) label.content = "Error in side, please re-enter."; Alternatief voor Convert.ToDouble F2= Functie die F1 oproept try F1() catch F1= Functie met mogelijke problemen Throw Exception Binnen het try blok kan zich een FormatException voordoen, nl: Parse De exception wordt afgehandeld in het catch block Programmeren in C# 18
Programmeren in C# 19 try-catch: regels Zet een try blok rond de code die je wil controleren op fouten Als in een statement een exception optreedt, stopt de uitvoering onmiddellijk Er wordt gesprongen naar het catch blok, waar de exception afgehandeld wordt Naam exceptionobject wordt niet gebruikt Kan extra info over fout meegeven Als de exception niet wordt opgevangen, wordt deze doorgegooid naar de oproepende methode Als ook deze ze niet kan opvangen à weer doorgooien Uiteindelijk kom je uit bij de Main() procedure à stack trace
Programmeren in C# 20 Een try-catch voorbeeld private void calculatebutton_click(object sender, EventArgs e) try DoCalc(); catch (FormatException exceptionobject) label.content = "Error in side, please re-enter."; K1 functie1() private void DoCalc() double side = Double.Parse(textBox.Text); label.content = String.Format("Area is 0 square units.", (side * side)); K2 functie2()
Programmeren in C# 21 Het exception object Bevat nuttige informatie over de aard van de fout Tip: lees deze informatie, dit zal je helpen bij het debuggen! Properties Message : kort bericht StackTrace : hierarchie van methodes die geleid hebben tot de exception Zie ook: Source, TargetSite, InnerException Methode ToString(): string voorstelling van deze exception MessageBox.Show(exceptionObject.Message); MessageBox.Show(exceptionObject.ToString());
Programmeren in C# 22 Classificatie s p e c i f i e k e r
Programmeren in C# 23 Opmerking Nog veel meer exceptie klassen Kennen van namen van excepties niet voldoende Bron moet gekend zijn Voor elke methode die je gebruikt, documentatie bekijken Bevat wat methode doet Argumenten Excepties die worden opgegooid
Overzicht Inleiding Try-Catch Combinatie Catch blokken Opgooien van exceptie Finally Zelf exceptie schrijven Programmeren in C# 24
Programmeren in C# 25 Meerdere exceptions in 1 catch... try Ofwel alle specifieke gevallen opvangen, zodat je een foutafhandeling hebt per geval SomeOperationWithIO(); catch (FileNotFoundException ex) MessageBox.Show("File not found, choose other file"); catch (EndOfStreamException ex) MessageBox.Show("End of stream: file corrupt");...
Programmeren in C# 26 Meerdere exceptions in 1 catch... try Ofwel 1 catch die alle subklassen van IOException behandelt. Dit is naar de gebruiker toe minder duidelijk. (Bestand niet gevonden of corrupt?) SomeOperationWithIO(); catch (IOException ex) MessageBox.Show("IOException occurred.");...
Programmeren in C# 27 Combinatie van catch blokken int bottom; int top = 100; try Vang elk type van exception afzonderlijk op bottom = Int32.Parse(textBox.Text); label.content = String.Format("Dividing into 100 gives 0", (100 / bottom)); catch (DivideByZeroException exceptionobject) label.content = "Error - zero: re-enter data."; catch (FormatException exceptionobject) label.content = "Error in number: re-enter."; catch (SystemException exceptionobject) MessageBox.Show(exceptionObject.ToString()); Regel: hoe algemener de exception (SystemException), hoe later opvangen in het try-catch statement (waarom?)
Programmeren in C# 28 Samenvatting Methode1() Methode2() Methode3() à Exception treedt op Uitvoering van Methode3() wordt onmiddellijk gestopt Als er een catch statement is, die deze Exception (of een superklasse ervan) opvangt, wordt deze uitgevoerd. De uitvoering gaat vervolgens verder na het try-catch blok. Als er geen catch statement is, gaat de Exception naar de oproeper (Methode2()), indien deze ook geen catch statement heeft naar Methode1(), enz. Als er helemaal geen catch wordt gevonden, breekt het programma af met een foutmelding. Exception propagation(voortplanting) K1 functie1() K2 functie2() K3 functie3()
Overzicht Inleiding Try-Catch Combinatie Catch blokken Opgooien van exceptie Finally Zelf exceptie schrijven Programmeren in C# 29
Programmeren in C# 30 Opgooien: een inleiding private int WordToNumber(string word) int result = 0; if (word == "ten") result = 10; else if (word == "hundred") result = 100; else if (word == "thousand") result = 1000; else throw new FormatException("Wrong input: " + word); return result; F2= Functie die F1 oproept try F1() catch F1= Functie met mogelijke problemen Throw Exception
Opgooien: een inleiding private void convertbutton_click(object sender, EventArgs e) try MessageBox.Show(Convert.ToString(WordToNumber("hXndred"))); catch (FormatException exceptionobject) MessageBox.Show(exceptionObject.Message); F2= Functie die F1 oproept try F1() catch F1= Functie met mogelijke problemen Throw Exception Programmeren in C# 31
Hoe afhandelen Zinvolle foutmelding naar de gebruiker toe, eventueel vragen om nieuwe invoer Opgelet, niet altijd gebruiker die invoer doet, invoer kan ook komen uit database Bij waarschijnlijke bugs, exceptions loggen naar bestanden of Event logs Nooit lege catch statements schrijven om exceptions te verbergen Programmeren in C# 32
Samengevat Methode A die exceptie opgooit throw WordNumber( ) F1= Functie met mogelijke problemen Throw Exception Methode B die Methode A aanroept en die exceptie opvangt try-catch ConvertButton_Click( ) F2= Functie die F1 oproept try F1() catch Programmeren in C# 33
Afhandelen Niet alle exceptions afhandelen, soms gewoon verkeerd programma en beter debuggen Vb IndexOutOfRangeException int[] a = new int[10]; for (int n=0; n<=10,n++) a[n]=25; Programmeren in C# 34
Overzicht Inleiding Try-Catch Combinatie Catch blokken Opgooien van exceptie Finally Zelf exceptie schrijven Programmeren in C# 35
Programmeren in C# 36 finally DatabaseConnection resource =...; try resource.open(); voer queries uit naar de database catch (SQLException exceptionobject) toon foutmelding finally // ruim de connectie op resource.close();
Finally blok Wordt altijd uitgevoerd Zelfs bij return in try Zelfs bij niet opgevangen catch Achteraan try-catch blok Programmeren in C# 37
Vergelijk try Protect one or more statements here. catch(exception e) Report and recover from the exception here. finally Perform any actions here common to whether or not an exception is thrown. try Protect one or more statements here. catch(exception e) Report and recover from the exception here. Perform any actions here common to whether or not an exception is thrown.
Overzicht Inleiding Try-Catch Combinatie Catch blokken Opgooien van exceptie Finally Zelf exceptie schrijven Programmeren in C# 39
Programmeren in C# 40 Zelf exception schrijven F2= Functie die F1 oproept try F1() catch finally F1= Functie met mogelijke problemen Throw Exception In bepaalde omstandigheden zijn de ingebouwde exceptions van het.net framework onvoldoende Bijvoorbeeld, je wil fouten die voor een bepaalde toepassing specifiek zijn, op dezelfde manier met exceptions afhandelen Hoe? Schrijf zelf een klasse die overerft van ApplicationException Exception klasse
Exception voor ongeldig emailadres Bv ongeldig als er geen @ en geen. na @ komt Kan met FormatException Eigen klasse is echter duidelijker. Richtlijnen kunnen specifiek meegegeven worden. Programmeren in C# 41
Programmeren in C# 42 Zelf exceptions schrijven public class InvalidEmailException : ApplicationException public InvalidEmailException(string message) : base(message) Voorzie steeds een constructor die een message parameter doorgeeft. Dit is de eigenlijke foutmelding
Zelf exceptions schrijven private void checkbutton_click(object sender, EventArgs e) try CheckAddress(textBox.Text); catch (InvalidEmailException ex) MessageBox.Show(ex.Message); private void CheckAddress(string email) if (!email.contains('@')) throw new InvalidEmailException(email + " does not contain @-sign!"); // other validation rules... F2= Functie die F1 oproept try F1() catch F1= Functie met mogelijke problemen Throw Exception Exception klasse Programmeren in C# 43
Programmeren in C# 44 Eigen exceptie schrijven 1. Nieuwe exceptie klasse aanmaken InvalidEmailException 2. Methode F1 schrijven die nieuwe exceptie opgooit (Throw) CheckAdress() 3. Methode F2 die methode F1 aanroept en die exceptie opvangt (Try-Catch) CheckButtonClick() F2= Functie die F1 oproept try F1() catch F1= Functie met mogelijke problemen Throw Exception Exception klasse 44
Samenvatting Programmeren in C# 45
Overzicht Inleiding Try-Catch Combinatie Catch blokken Opgooien van exceptie Finally Zelf exceptie schrijven Programmeren in C# 46
Oefening 17.1 Deling van 2 gehele getallen Voorzie 2 tekstvakken voor invoer van 2 getallen. Laat de resultaten van de 2 delingen zien in 2 labels als je op knop duwt. Voeg de volgende exceptionhandelingentoe: FormatException DivideByZeroException Programmeren in C# 47
Programmeren in C# 48 Oefening 17.2 Methode om kwadratische vergelijking op te lossen LosOp(a,b,c,opl1,opl2); Opl1 en Opl2 met referenties retourneren Exception Als Discriminant negatief is, dan ArithmeticException met gepaste foutmelding Als a=0, dan ArithmeticException met gepaste foutmelding Als a,b,c geen doubles zijn, dan FormatException
Programmeren in C# 49 Oefening 17.7 1. BankException:ApplicationException BankRekening Property saldo met get Storting 2. Gooit exception bij saldo boven 2500 Opname 2. Gooit exception bij waarde onder 0 GUI Knop voor saldo Textbox voor bedrag (+/-) Label voor saldo Code achter GUI Event bij knopklik 3. Try-catch: FormatException, BankException