Wanneer je in een programma een keuze moet maken, dan gebruik je een if - else
statement. In veel gevallen is dat ook de beste manier om dat te doen. Maar wanneer je specifieke waarden wil behandelen, dan kan het switch
statement soms eenvoudiger zijn. Vergelijk even de volgende twee voorbeelden, waarin aan de hand van het nummer van de maand de maandnaam bepaald wordt.
// Met if-else
public static string MonthToString(int month)
{
string result = string.Empty;
if(month == 1) {
result = "January";
} else if (month == 2) {
result = "February";
} else if (month == 3) {
result = "March";
}
// ...
return result;
}
// Met switch
public static string MonthToString(int month)
{
string result = string.Empty;
switch(month) {
case 1: result = "January";
break;
case 2: result = "February";
break;
case 3: result = "March";
break;
// ...
}
return result;
}
Het is niet zo dat het switch statement korter is, maar soms is het wel beter leesbaar. Onthoud alvast het volgende:
switch
statement kijkt welke waarde de variabele tussen haakjes heeft (in het voorbeeld is dit month) en springt naar de case met de overeenkomende waarde. Deze case wordt uitgevoerd.case
statement.break
statement. Dit zorgt ervoor dat het switch
statement afgesloten wordt na het uitvoeren van de case.Een handige extra feature van een switch
statement is dat je de mogelijke acties (cases) kan afsluiten met default
. Dit is een speciale case die gebruikt wordt wanneer de waarde voldoet aan geen enkele case. Zo kan je bijvoorbeeld in het voorbeeld van hierboven een ongeldige maandnummer detecteren.
// Indien de variabele month geïnitialiseerd wordt op een waarde die niet tussen 1 en 12
// (grenzen inbegrepen) ligt, dan voert het switch statement het instructieblok bij default uit.
public static string MonthToString(int month)
{
string result = string.Empty;
switch(month)
{
case 1: result = "January";
break;
case 2: result = "February";
break;
case 3: result = "March";
break;
// ...
case 12: result = "December";
break;
default: result = "Invalid";
Console.WriteLine("Invalid Month detected");
break;
}
return result;
}
Vanaf C# 7.0 is het mogelijk om andere operatoren dan ==
te gebruiken als voorwaarde bij case. Bij oudere versies van C# kon er enkel met een exacte waarde vergeleken worden, zoals in de voorbeelden hierboven. Vanaf C# 7.0 kan er ook met andere operatoren gewerkt worden zoals het voorbeeld hieronder aantoont.
public static string NumberRange(int number)
{
string result= String.Empty;
switch (number)
{
case int n when (n >= 7):
result=($"I am 7 or above: {n}");
break;
case int n when (n >= 4 && n <= 6):
result = ($"I am between 4 and 6: {n}");
break;
case int n when (n <= 3):
result = ($"I am 3 or less: {n}");
break;
}
return result;
}
static void Main(string[] args)
{
Console.WriteLine(NumberRange(10));
}
Dikwijls zal je een switch gebruiken in combinatie met enumeraties. Dit heeft weer een extra voordeel: de compiler zal je waarschuwen wanneer je een waarde vergeet.
In onderstaand voorbeeld wordt de variabele fontSize geïnitialiseerd a.h.v. de opties uit de enumeratie ScreenSize.
public enum ScreenSize { Small, Medium, Normal, Large};
public static int ScreenToFontSize(ScreenSize size) {
int fontSize = 0;
switch(size) {
case ScreenSize.Small:
fontSize = 8;
break;
case ScreenSize.Medium:
fontSize = 12;
break;
case ScreenSize.Normal:
fontSize = 16;
break;
}
return fontSize;
}
In het voorbeeld hierboven zal de compiler opmerken dat je ScreenSize.Large
niet behandeld hebt. Je kan dat oplossen door een extra case
toe te voegen, maar ook door de eindigen met een default
optie.
Je kan ook waarden tesamen behandelen. Dit kan handig zijn als verschillende mogelijkheden tot hetzelfde resultaat leiden, zoals in het volgende voorbeeld waar voor bepaalde waarden van de variabele punt dezelfde case uitgevoerd moet worden.
public static string Beoordeel(int punt) {
string result = string.Empty;
switch(punt) {
case 10:
case 9:
result = "Very Good";
break;
case 8:
case 7:
result = "Sufficient";
break;
case 6:
result = "Nearly failed!";
break;
default:
result = "Try Again";
break;
}
return result;
}
Tot slot kan je ook dadelijk een return
gebruiken om je functie te verlaten. In dat geval heb je geen break
statement nodig. Hieronder zie je nogmaals het voorbeeld uit het vorige deel, maar nu met directe returns. Je schrijft in dit geval de default in de vorm van een return buiten het switch
statement. Zo kan de compiler zien dat je in elk geval een waarde teruggeeft en vermijd je een foutmelding.
public static string Beoordeel(int punt) {
switch(punt) {
case 10:
case 9:
return "Very Good";
case 8:
case 7:
return "Sufficient";
case 6:
return "Nearly failed!";
}
return "Try Again";
}
Open het project oefening-switch-1 en maak de oefeningenreeks