Switch

Verschil if - else en switch

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:

  • Het 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.
  • Elk geval dat je wil behandelen definieer je met een case statement.
  • Elke case moet je afsluiten met een break statement. Dit zorgt ervoor dat het switch statement afgesloten wordt na het uitvoeren van de case.

Default waarden

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;
}

Case statement met when voorwaarde

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));

    }

Enumeraties

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.

Waarden combineren

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;
}

Direct Return

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


Previous section:
Next section:
Navigatie