Je maakt bijvoorbeeld een toepassing die twee getallen die door de gebruiker worden ingegeven optelt en de som op het scherm toont.
Wat gebeurt er als de gebruiker letters invult, of helemaal niks?
De bedoeling van dit hoofdstuk is dat je dergelijke mogelijke probleemsituaties kan inschatten, en softwarematig een oplossing biedt, zonder dat je toepassing "crasht".
Hierbij wordt niet bedoeld dat je elk probleem moet kunnen oplossen - letters kunnen we nu eenmaal niet optellen -, je kan de gebruiker wel op de hoogte stellen van het probleem en informeren hoe dit probleem kan opgelost worden door bijvoorbeeld een bericht te tonen: "Gelieve numerieke waarden in te geven.".
Je kan dus in je programmacode een pad voorzien voor het goede verloop van de toepassing, maar je moet zeker rekening houden dat dit verloop wel eens verstoord kan worden.
Het is belangrijk in te zien dat we dergelijke onvoorziene omstandigheden in een programma uitzonderingen of exceptions noemen, deze kunnen we gestructureerd in programmacode afhandelen. Fouten daarintegen zijn verkeerde denkwijzen of verkeerde programmaalgoritmes: als je de gebruiker belooft twee getallen op te tellen, maar je berekent het verschil, dan zal je programma wellicht niet vastlopen, maar de gebruiker zal ook niet echt gelukkig zijn.
try
{
//statements die mogelijks een fout kunnen opleveren
}
catch
{
//statements die uitgevoerd worden wanneer een fout optreedt
}
private void btnTelOp_Click(object sender, RoutedEventArgs e)
{
int getal1 = int.Parse(txtGetal1.Text);
int getal2 = int.Parse(txtGetal2.Text);
int resultaat = BerekenSom(getal1, getal2);
lblSom.Content = resultaat.ToString();
}
int BerekenSom(int getalL, int getalR)
{
return getalL + getalR;
}
Het programma wordt onderbroken en een foutmelding verschijnt:
Stop de toepassing:
Het intikken van tekst in plaats van een numerieke waarde levert dus een FormatException op: de ingetikte tekst kan onmogelijk naar het gewenste Formaat (int) omgezet worden en de toepassing houdt het voor bekeken.
Als programmeur zien wij deze melding verschijnen in Visual Studio, daar we wanneer de toepassing starten de Visual Studio Debugger aan het werk zetten. Visual Studio kijkt achter onze schouder mee bij het werken met de toepassing en grijpt in wanneer het verkeerd loopt.
Wanneer je dit programma verspreidt voor gebruik, dan voeren de gebruikers een .exe-bestand uit, los van Visual Studio.
Het bestand WpfErrors.exe vind je in de /bin/Debug map van je huidige toepassing.
Deze melding verschilt naargelang de versie van Windows (je weet wel: "dit programma heeft een ongeldige bewerking uitgevoerd en zal worden afgesloten...").
Het is leuker voor de gebruiker dat het programma blijft werken en een aangepaste melding verschijnt.
try
{
int getal1 = int.Parse(txtGetal1.Text);
int getal2 = int.Parse(txtGetal2.Text);
int resultaat = BerekenSom(getal1, getal2);
lblSom.Content = resultaat.ToString();
}
catch (FormatException fEx)
{
MessageBox.Show("Gelieve numerieke waarden in te geven.\n\nDetails: "
+fEx.Message
,"Ingavefout");
}
We vliegen er weer uit!
Deze keer heb je een OverFlowException veroorzaakt: het getal is te groot om te stockeren in een variabele van het type int.
catch (OverflowException oEx)
{
MessageBox.Show("Getal is te groot of te klein.\n\nDetails: "
+ oEx.Message
+"\n\nMin: " +int.MinValue.ToString() +" Max: " +int.MaxValue.ToString()
, "Ingavefout");
}
Op deze manier kan je een aparte foutafhandeling voorzien voor elke fout die kan optreden.
Wil je deze moeite niet doen, dan kan je een joker gebruiken door gebruik te maken van een Exception:
catch (Exception Ex)
{
MessageBox.Show("Controleer de ingevoerde waarden.\n\nDetails: "
+ Ex.Message
, "Ingavefout");
}
catch
{
MessageBox.Show("Controleer de ingevoerde waarden.\n\nDetails: "
, "Ingavefout");
}
De bovengrens voor een int (Int32) is 2147483647 (231 - 1).
Doordat de bovengrens van int wordt overschreden wordt in een berekening doorgegaan vanaf de benedengrens.
Dit probleem rijst doordat de C#-compiler in stilte toestaat dat de berekening leidt tot een overflow.
De reden dat dit wordt toegestaan is dat een controle op overflow voor elke berekening zou leiden tot een gigantisch performatieverlies.
Eigenlijk gaan we er hier van uit dat je voor berekeningen steeds een realistische keuze in datatype maakt waarbij je aanneemt dat de grens (in de verste verte) niet bereikt zal worden.
Soms kan je dit echter niet voorzien, in dergelijke gevallen kan je een check doen op eventuele overflow:
int BerekenSom(int getalL, int getalR)
{
return checked(getalL + getalR);
}
Of een checked codeblok:
int BerekenSom(int getalL, int getalR)
{
checked
{
return getalL + getalR;
}
}
Je doet dus een controle in de methode, maar wenst dit kenbaar te maken op de plaats waar de methode werd aangeroepen.
Dit kan je door in de methode een Exception op te werpen (throw). Deze Exceptie kan je dan afhandelen wanneer je de methode aanroept.
int BerekenSom(int getalL, int getalR)
{
int som = checked(getalL + getalR);
if (som < 0)
throw new ArgumentOutOfRangeException("Mag niet negatief zijn");
return som;
}
Pas nu ook de code aan voor het drukken op de knop zodat de ArgumentOutOfRangeException wordt opgevangen:
catch (ArgumentOutOfRangeException aEx)
{
MessageBox.Show("Verkeerde som\n\nDetails: "
+ aEx.Message
, "Ingavefout");
}
Wanneer een Exception optreedt wordt de flow van een programma veranderd.
Soms is het nodig code te schrijven die moet uitgevoerd worden, fout of niet, bepaalde statements moeten uitgevoerd worden.
Dit kan je bereiken door na een try-blok een finally blok te voorzien.
try
{
... statements die een Exception kunnen veroorzaken...
}
finally
{
... statements die zeker uitgevoerd moeten worden...
}
Wanneer we nu ook catch-blokken voorzien ziet de code er als volgt uit.
try
{
... statements die een Exception kunnen veroorzaken...
}
catch
{
... afhandelen van Exceptions ...
}
finally
{
... statements die zeker uitgevoerd moeten worden...
}
Toepassing van finally zal je vinden in het steeds vrijgeven van bronnen (geopende files, databaseconnecties), zelfs wanneer onderweg iets is foutgelopen.
| Meer tutorials: |
| leer ook: | html | | xhtml | | css | | asp | | asp.net | | c# | | ado.net | | linq | | ajax | | java | | javascript |