Basis concepten leren in C# (deel 2)

Rekenkundige operatoren

In C# zijn een aantal rekenkundige operatoren voorzien die ons toelaten om te rekenen met alle datatypes die getallen bevatten (zie tabel in de sectie data types in “Basis concepten leren in C# (deel1)“).

Volgende operatoren zijn ondersteund: +, -, \, * en Mod. Wil je uitgebreidere wiskundige handelingen uitvoeren, kijk dan naar de ingebouwde “Math” klasse.

De eerste 4 operatoren laten toe om op te tellen, af te trekken, te delen en te vermenigvuldigen. De 5 de operator deelt het linkse getal door het rechts en geeft de rest van deling terug.

Enkele voorbeelden:

 int resultaat = 0; 
 resultaat = 5 + 10; 
 //15 
 resultaat = 5 * 2; 
 //10 
 resultaat = 5 - 1; 
 //4 
 resultaat = 7 / 3; 
 //2 want Integer kunnen geen komma-getallen 'opslaan 
 //1 de rest van de deling van 7 door 3 is 1 
 resultaat = 7 % 3; 

Flow control

If… Then …Else

Het If…Then…Else… statement laat je toe om codeblokken te laten uitvoeren slechts als aan een bepaalde conditie voldaan is of niet. Het Ifgedeelte bevat de eerste conditie, daarna hebben we 0 of meerdere ElseIfblokken die eventueel andere condities bevatten en uiteindelijk hebben we eventueel het Else blok dat zal uitgevoerd worden indien aan geen van de andere voorwaardes voldaan wordt.

if (x > 0) { 
 //Als X groter is dan 0 wordt deze codeblok 
 uitgevoerd(); 
 } 
 else if (x < 0) { 
 //Als X kleiner is dan 0 wordt deze codeblok 
 uitgevoerd(); 
 } 
 else { 
 //In alle andere gevallen wordt deze codeblok 
 uitgevoerd(); 
}

Het is tevens mogelijk om meerdere condities te vergelijken met behulp van de AndAlso, OrElse en Not-operatoren. Een voorbeeld:

if (x > 0 && y > 0) { 
} 
//Als X en y groter zijn dan 0 wordt deze codeblok 
uitgevoerd 
 else if (x < 0 || y < 0) { 
 //Als X of Y kleiner is dan 0 wordt deze 
codeblok 
 uitgevoerd(); 
} 
else if (!(x == 0)) { 
} 
else { 
 //Als X niet 0 is wordt deze codeblok uitgevoerd 
 //In alle andere gevallen wordt deze codeblok 
 uitgevoerd(); 
}

Select Case

Het Select Case-statement is niet zo veelzijdig als het If…Then…Else…- statement aangezien het slechts één expressie kan valideren tegen een lijst van waardes. Voorbeeld:

switch (x) { 
 case 1: 
 break; 
 //Wordt uitgevoerd als X = 1 
 case 2: 
 break; 
 //Wordt uitgevoerd as X = 2 
 case 3: 
 break; 
 //Wordt uitgevoerd als X = 3 
 default: 
 break; 
 //Wordt uitgevoerd in alle andere gevallen 
}

For…Next

Je kan het For…Next-statement gebruiken om een aantal maal over hetzelfde stuk te loopen. De syntax is als volgt:

for (datatype teller = start; teller <= eind; teller += 
stapgrootte) 
{ 
}

Het Step-gedeelte is optioneel en laat je toe om achterwaarts te tellen of te verhogen met waardes verschillend van 1. Indien je dit deel weglaat zal de stapgrootte 1 zijn. Je kan eventueel uit de loop springen door het keyword Exit For te gebruiken. Verder is het ook mogelijk om een nieuwe iteratie te beginnen zonder de rest van het codeblok uit te voeren met behulp van het Continue-statement. Een volledig voorbeeld van het For…Next Statement:

for (int teller = 0; teller <= 10; teller++) { 
 if (teller == 5) { 
 continue; 
 } 
 else if (teller == 8) { 
 break; 
 } 
 Console.WriteLine("Waarde:" + teller); 
}

Bovenstaande code zal het codeblok tussen For en Next gaan herhalen. De teller wordt initieel op 0 gezet en wordt bij elke iteratie 1 opgehoogd. Wanneer de teller 5 bedraagt zal het If-statement ervoor zorgen dat de rest van het blok niet uitgevoerd wordt maar meteen met een volgende iteratie wordt verdergegaan. Dit betekent dat de regel Console.WriteLine(“De teller….”) niet zal uitgevoerd worden in de 5de iteratie. Wanneer de teller 8 bereikt zal de loop vroegtijdig afgebroken worden.

For Each

Met een For Each statement kunnen we elk element in een collectie (Of correcter: al de elementen van object dat IEnumerable implementeert) overlopen zonder dat we de grootte van deze collectie kennen. Meer informatie over collectie in deel 3 van deze cursus. Op dit moment bekijken we een collectie als een lijst met waardes:

// Met dit blok maken we een lijst en we voegen er 3 
getallen aan toe
List<int> lijst = new List<int>(); 
lijst.Add(1); 
lijst.Add(2); 
lijst.Add(3);

Met een For Each-loop kunnen we nu over deze lijst lopen. De syntax van een For Each-loop is als volgt:

foreach (datatype element in lijst) 
{ 
}

Met deze syntax kunnen we dus de eerder gedefinieerde lijst als volgt overlopen:

foreach (int getal in lijst) 
{ 
}

Do…Loop

Het Do…Loop-statement laat, net zoals het For…Next-statement, toe om meermaals over hetzelfde codeblok te lopen. Het is echter flexibeler dan het For…Next-statement vanwege de condities die we kunnen bepalen. Onderstaand voorbeeld is een basisdeclaratie van een Do…Loop-lus. Let op: dit is een oneindige lus, aangezien er geen condities voorzien zijn.Om ervoor te zorgen dat het programma niet crasht, moet je een Exit Dostatement in de lus plaatsen.

do { 
 break;
 } 
while (true);

We hebben twee mogelijkheden en twee plaatsen om condities te plaatsen
voor het beëindigen van de loop.
We kunnen een conditie bovenaan of onderaan onze loop plaatsen. Indien we een conditie bovenaan plaatsen kan het zijn dat de loop nooit uitgevoerd wordt, indien we ze onderaan plaatsen, wordt de loop minimaal 1 keer uitgevoerd. Verder kunnen we ofwel de Whiel-constructie gebruiken (blijf loopen zolang de conditie waar is) of de Until-constructie (blij loopen zoalng de conditie onwaar is). Enkele voorbeelden:

 // Deze loop zal uitgevoerd worden zolang x groter 
is dan 0 
 //Indien x bij de start reeds kleiner is dan 0 dan 
wordt de loop nooit uitgevoerd
 while (x > 0) { 
 x = x + 1; 
 }
 // Deze loop zal uitgevoerd worden zolang x groter is 
dan 0
 //Indien x bij de start reeds kleiner is dan 0 dan 
wordt de loop toch één keer uitgevoerd
 do { 
 x = x - 1; 
 } 
 while (x > 0); 
 
 // Deze loop zal uitgevoerd worden tot x groter is 
dan 0 
 //Indien x bij de start reeds groter is dan 0 dan 
wordt de loop toch één keer uitgevoerd 
 do { 
 x = x + 1; 
 } 
 while (!(x > 0)); 
 
 // Deze loop zal uitgevoerd worden tot x groter is 
dan 0 
 //Indien x bij de start reeds groter is dan 0 dan 
wordt de loop nooit uitgevoerd 
 while (!(x > 0)) { 
 x = x + 1; 
 }

Error Handling

In de .NET-wereld worden Errors behandeld als volwaardige objecten. Het type dat hiervoor gehanteerd is het Exception-object. Het voordeel van deze manier van werken is dat we volledige informatie kunnen verzamelen over het type, de bron en de reden van de error. Het framework laat ons ook toe om onverwachte fouten op te vangen en indien mogelijk elegant af te handelen. Het grote probleem met het afhandelen van errors in omgevingen voorgaand aan .NET is het feit dat niemand het eens werd over een enkele beste aanpak van het probleem. Een aantal voorbeelden: In Windows DLL’s, geschreven in C, worden errorcodes teruggegeven in de vorm van een getal. Dit werd op een zeer verwarrende manier gedaan, een 0 kan in sommige gevallen “succesvol” betekenen, in andere gevallen betekent het een error. In de COM-based wereld (Visual Basic, voor .NET) werden error-codes teruggegeven als een 32-bit HRESULT. Java en C++ waren de eerste talen die Errors gingen afhandelen op een manier gelijkaardig aan de .NET-methode. Je kan een error definiëren als een onverwacht situatie gedurende de uitvoer van een programma. Wanneer dit gebeurt wordt er gezegd dat de code een exception “gooit”. Een ander stuk code zal deze exception moeten “opvangen” (Engels: throw-catch) Een exception kan opgevangen kan gebeuren in dezelfde methode als waarin de exception gegooid werd. Wanneer dit niet gebeurt wordt de exception verder gegooid naar de aanroepende methode. Indien ook deze de error niet opvangt zal de exception weer verder gegooid worden naar de volgende aanroeper. Dit blijft gebeuren tot er geen verder aanroepende methode meer is. Dan wordt er een standaard foutboodschap aan de gebruiker getoond. Het afleggen van deze weg door een exception noemen we “Bubbling”. Een voorbeeld van zo’n exception kunnen we krijgen door een deling door 0 uit te voeren:

int x = 0; 
x = x / 0;

Indien we deze code uitvoeren, en we vangen de exception niet op, dan zal er een standaard foutboodschap getoond worden (Unhandled Exception).

Try… Catch… Finally

Om Exceptions op te vangen maken we gebruik van het Try…Catch…Finally statement. Dit ziet er als volgt uit:

 try { 
    //voer hier code uit die een exception kan geven
 } 
 catch (Exception ex) { 
    //Onderneem actie als er een exception optreedt
 } 
 finally { 
    //Voer deze code altijd uit
 }

In het eerste gedeelte (Try) plaatsen we de code waarvan we verwachten dat ze eventueel een exception zal gooien. In het tweede deel (Catch) plaatsen we de code die uitgevoerd moet worden als er een exception optreed. De exception zal nu niet meer verdergaan en het programma wordt verder uitgevoerd. We kunnen informatie over de error verkrijgen door het object ex (van het type exception) te inspecteren.
In het derde deel (Finally), plaatsen we code die, ongeacht of er een error optrad of niet, altijd uitgevoerd moet worden.
We passen dit toe op de deling door 0 die we eerder deden:

try { 
    int x = 10; 
    x = x / 0; 
 } 
catch (Exception ex) { 
    Console.WriteLine("Er trad een error op:" + ex.Message); 
 } 
finally { 
    Console.WriteLine("Try...Catch-blok werd uitgevoerd"); 
 }

In bovenstaand codeblok zal er geprobeerd worden om x te delen door 0. Indien dit faalt wordt er op het scherm een boodschap getoond die de message zal tonen die het exception-object bevat. Er wordt sowieso op het einde een boodschap op het scherm getoond dat het try..catch-blok werd uitgevoerd.

Enumeraties

Een enumeratie is een constructie waarbij we gerelateerde constante waardes kunnen opslaan. De constante waardes worden voorgesteld door een naam die correspondeert met een nummer. Onderstaand voorbeeld groepeert een aantal vormen en kent aan elke vorm een nummer toe:

public enum Shape
{ 
 Driehoek = 0, 
 Vierkant = 1, 
 Cirkel = 2 
}

Wanneer we de getallen zouden weglaten, zal he framework deze getallen zelf gaan bepalen (0 voor het eerste, 1 voor het tweede, …). Het is mogelijk om deze getallen compleet andere waardes te geven, maar dit is niet aangeraden.