enum
Last updated
Last updated
Helm op alsjeblieft!
enum
is een erg onderschat concept bij beginnende programmeurs. Enums zijn wat raar in het begin, maar van zodra je er mee weg bent zal je niet meer zonder kunnen en zal je code zoveel eleganter en stoerder worden. Zet je helm dus op en begin er aan!
Stel dat je een programma moet schrijven dat afhankelijk van de dag van de week iets anders moet doen. In een wereld zonder enums (enumeraties, letterlijk opsommingen) 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 (bv. "woensdag"
)
int
De waarde van de dag staat in een variabele int dagKeuze
. We bewaren er 1 in voor maandag, 2 voor dinsdag, enz. Vervolgens kunnen we dan schrijven:
Deze oplossing heeft 2 grote nadelen:
Wat als we per ongeluk dagKeuze
een niet geldige waarde geven, zoals 9, 2000 of -4 ?
De code is niet erg leesbaar. Wat was dagKeuze ==2
nu weer? Was 2
nu dinsdag of woensdag (want misschien was maandag 0 i.p.v. 1) ?
Laten we tweede manier eens bekijken: de waarde van de dag bewaren we in een variabele string dagKeuze
. We bewaren de dagen als "maandag"
, "dinsdag"
, enz.
De code wordt nu wel leesbaarder, maar toch is ook hier 1 groot nadeel:
De code is veel foutgevoeliger voor typefouten. Wanneer je "Maandag"
i.p.v. "maandag"
bewaart dan zal de if al niet werken. Iedere schrijffout of variant zal falen.
Enumeraties (enum) zijn een C# syntax dat bovenstaand probleem oplost en het beste van beide slechte oplossingen samenvoegt :
Leesbaardere code.
Minder foutgevoelige code, en dus minder potentiële bugs.
VS kan je helpen met sneller de nodige code te schrijven.
Het keyword enum
geeft aan dat we een nieuw datatype maken dat maar enkele mogelijke waarden kan hebben. Nadat we dit nieuwe datatype hebben gedefinieerd kunnen we variabelen van dit nieuwe datatype aanmaken. Deze variabelen mogen enkel waarden bevatten die in het datatype werden gedefinieerd. Ook zal IntelliSense van Visual Studio je de mogelijke waarden helpen invullen.
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;
Zelf een enum
type maken en gebruiken gebeurt in 2 stappen:
Het nieuwe datatype en de mogelijke waarden definiëren.
Waarden van het nieuwe enumtype aanmaken en gebruiken in je code.
We maken eerst een enum type aan. In je console-applicaties moet dit binnen class Program
gebeuren, maar niét binnen de Main
methode:
Als volgt dus:
We hebben nu letterlijk een nieuw datatype aangemaakt, genaamd Weekdagen
.
Net zoals int
, double
enz. kan je nu ook variabelen van het type Weekdagen
aanmaken. Hoe cool is dat!?
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 krijgen die in het type gedefinieerd werden. De code is nu ook een pak leesbaarder geworden.
Ook de beslissingsstructuren worden leesbaarder:
of een switch:
Visual Studio houdt van enums (ik ook trouwens) en zal je helpen bij het schrijven van een switch
indien de test-variabele een enum-type bevat. Hoe?
Schrijf switch
en druk op 2 maal op tab. Normaal verschijnt er nu een "prefab" switch structuur met een test-waarde genaamd switch_on
die een gele achtergrond heeft.
Overschrijf switch_on
met de variabele die je wilt testen (bv. dagKeuze
).
Klik nu met de muis eender waar binnen de accolades van de switch
.
Profit!
De waarde van een enum-variabelen wordt intern als een int
bewaard. In het geval van de Weekdagen
zal maandag
standaard de waarde 0 krijgen, dinsdag 1, enz.
Volgende conversies met behulp van casting zijn dan ook perfect toegelaten:
Wil je dus bijvoorbeeld 1 dag bijtellen dan kan je schrijven:
Let er wel op dat je geen extra dag op Zondag probeert bij te tellen. Dat zal niet werken.
Standaard worden de enum waarden intern dus genummerd beginnende bij 0. Je kan dit ook manueel veranderen door bij het maken van de enum
expliciet aan te geven wat de interne waarde moet zijn, als volgt:
De dagen zullen nu vanaf 1 genummerd worden, dus WeekDagen.Woensdag
zal de waarde 3 hebben.
We kunnen ook nog meer informatie meegeven, bijvoorbeeld:
In dit geval zullen Maandag tot Vrijdag intern als 1 tot en met 5 bewaard worden, Zaterdag als 50, en Zondag als 60.
De individuele enum waarden moeten steeds met een hoofdletter starten.
Heel vaak zal je een programma schrijven waarbij de gebruiker een keuze moet maken uit een menu of iets dergelijks. Dit menu kan je voorstellen met een enum. Het probleem is vervolgens vragen wat de keuze van de gebruiker is en deze dan verwerken. Je zou dit kunnen doen met behulp van een reeks if-testen (if(userinput=="demo")
)...Maar waarom niet de kracht van enum
benutten?!
Volgende code toont hoe je dit kunt doen:
Sinds .NET 5 uitkwam, is er een meer gebruiksvriendelijke manier verschenen om een string te parsen naar een enum variabele. Hierbij wordt gebruikt gemaakt van generics (herkenbaar aan < >
), een concept dat uit de doeken wordt gedaan in de appendix van dit boek.
Echter, zelfs zonder generics te kennen zou volgende code toch begrijpbaar moeten zijn. We gebruiken terug het eerder gedefinieerde Menu
type en de nieuw beschikbare Enum.Parse< >
- methode :
We plaatsen tussen de < >
het enum datatype naar waar we willen parsen.
Optioneel kan je via een tweede argument van het type bool aangeven of de parsing hoofdlettergevoelig is (false
) of niet (true
) :
De eerste kennismaking met enumeraties is wat bevreemdend: je kan plots je eigen datatypes aanmaken?! Van zodra je ze in de vingers hebt zal je ontdekken dat je veel leesbaardere code kunt schrijven én dat Visual Studio je kan helpen met het opsporen van bugs.
Wanneer gebruik je enum
? Telkens je één of meer variabelen nodig hebt, waarvan je perfect op voorhand weet welke mogelijke waarden ze mogen hebben. Ze worden bijvoorbeeld vaak gebruikt in finite state machines.
Bij game development willen we bijhouden in welke staat het programma zich bevindt: Intro
, Startmenu
, Ingame
, Gameover
, Optionsscreen
, enz. Dit is een typisch enum
verhaal. We definiëren hiervoor het volgende type:
En vervolgens kunnen we dan met een eenvoudige switch in ons hoofdprogramma snel de relevante code uitvoeren:
Een ander typisch voorbeeld is schaken. We maken een enum om de speelstukken voor te stellen (Pion, Koning, Toren
enz.) en kunnen hen dan laten bewegen en vechten in uiterst leesbare code:
Ah, de tijden zonder enum
. Ik weet nog hoe we onze grotten beschilderden zonder ons druk te moeten maken in enumeraties. Om maar te zeggen: je kan perfect leven zonder enum
. Vele programmeurs voor je hebben dit bewezen. Echter, van zodra ze enum
ontdekten (en begrepen) zijn nog maar weinig programmeurs er terug van afgestapt.