Met klassen kan je dus complexe concepten zoals een lening modelleren in code. Soms hoeft het niet zo complex, maar is het toch nuttig om wat meer structuur te voorzien dan met heel brede datatypes zoals int en string. Met een string kan je bijvoorbeeld om het even welke tekst voorstellen, dus oneindig veel mogelijkheden. Met een byte kan je een getal tussen 0 en 255 voorstellen. Met de andere getaltypes kan je een getal in een ander bereik voorstellen. Soms matchen de waarden die je kan voorstellen niet met de mogelijkheden in het probleemdomein.
Als je de mogelijkheden in het probleemdomein op voorhand kan vastleggen, is het vaak handig gebruik te maken van een enumeratie (enum). Een enumeratie is een opsomming van alle mogelijke waarden voor een variabele van een bepaald type.
Stel dat je een programma moet schrijven dat afhankelijk van de dag van de week iets anders moet doen. Zonder enums zou je dit kunnen schrijven op 2 zeer foutgevoelige manieren:
Met een int
die een getal van 1 tot en met 7 kan bevatten
Met een string
die de naam van de dag bevat
Beide hebben tekortkomingen, omdat ze niet goed genoeg overeenstemmen met de mogelijkheden in de werkelijkheid.
De waarde van de dag staat in een variabele int dagKeuze
. We bewaren er 1 in voor Maandag, 2 voor dinsdag, enzovoort.
Deze oplossing heeft 2 grote nadelen:
Wat als we per ongeluk dagKeuze
een niet geldige waarde geven, zoals 9, 2000, -4, etc. ? We kunnen daar wel conditionele code voor voorzien, maar de compiler zal ons niet waarschuwen als we dat vergeten!
De code is niet erg leesbaar. dagKeuze==2
? Was dat nu maandag, dinsdag of woensdag (want misschien beginnen we te tellen vanaf zondag, of misschien beginnen we te tellen vanaf 0). Je kan wel afspraken maken binnen je team, maar het is altijd mogelijk een afspraak te vergeten.
De waarde van de dag bewaren we nu in een variabele string dagKeuze
. We bewaren de dagen als "maandag"
, "dinsdag"
, etc.
De code wordt nu wel leesbaarder dan met 1, maar toch is ook hier 1 groot nadeel:
De code is veel foutgevoeliger voor typfouten. Wanneer je "Maandag"
i.p.v. "maandag"
bewaart dan zal de if
al niet werken. Iedere schrijffout of variant zal falen.
Het keyword enum
geeft aan dat we een nieuw datatype maken. Gelijkaardig aan wat we voor een klasse doen, dus. Wanneer we dit nieuwe type hebben gedefinieerd kunnen we dan ook variabelen van dit nieuwe type aanmaken (dat is waarom we spreken van een "datatype"). Anders dan bij een klasse beperken we tot alleen de opgesomde opties.
In C# zitten al veel enum
-types ingebouwd. Denk maar aan ConsoleColor
: wanneer je de kleur van het lettertype van de console wilt veranderen gebruiken we een enum-type. Er werd reeds gedefinieerd wat de toegelaten waarden zijn, bijvoorbeeld: Console.ForegroundColor = ConsoleColor.Red;
Achter de schermen worden waarden van een enum type nog steeds voorgesteld als getallen. Maar je gebruikt deze getallen niet rechtstreeks en dat verkleint de risico's.
Zelf een enum
type gebruiken gebeurt in 2 stappen:
Het type en de mogelijke waarden definiëren
Variabele(n) van het nieuwe type aanmaken en gebruiken in je code
Stap 1: het type definiëren
We maken eerst een enum type aan. Wij zullen dit doen in een aparte file met dezelfde naam als het nieuwe datatype. Bijvoorbeeld:
Vanaf nu kan je variabelen van het type Weekdagen
aanmaken. Merk op dat er geen puntkomma voorkomt. De syntax is ongeveer dezelfde als die voor de definitie van een klasse.
Stap 2: variabelen van het type aanmaken en gebruiken.
We kunnen nu variabelen van het type Weekdagen
aanmaken. Bijvoorbeeld:
En vervolgens kunnen we waarden aan deze variabelen toewijzen als volgt:
Kortom: we hebben variabelen zoals we gewoon zijn, het enige verschil is dat we nu beperkt zijn in de waarden die we kunnen toewijzen. Deze kunnen enkel de waarden zijn die in het type gedefinieerd werden. De code is nu ook een pak leesbaarder geworden.
Eens je met enums aan het werken bent in je programma, kan je gerust zijn dat deze een geldige waarde bevatten. Er is alleen het probleem dat je soms een van de mogelijkheden moet krijgen van de gebruiker. Een waarde van een enum type rechtstreeks intypen gaat niet. Net zoals wanneer je een getal inleest, is er een omzetting nodig. Het verschil is dat we hier een dubbele omzetting doen: van tekst naar getal en dan van getal naar enum waarde.
Je kan dit als volgt doen:
Dit werkt en je hoeft de achterliggende getallen voor de waarden niet te kennen. Er zijn meer geavanceerde mogelijkheden, maar dit volstaat op dit punt.