• Een datum die de gebruiker intypt, lees je in met DateTime.Parse(invoer, new System.Globalization.CultureInfo("nl-BE")). Zonder die cultuur leest een Engelstalige pc 11/9 als 9 november.
  • AddDays en co. veranderen je datum niet: ze geven een nieuwe DateTime terug die je zelf bewaart.
  • DateTime.Today is vandaag zonder uur. DateTime.Now heeft ook het uur, en dat telt mee als je datums aftrekt.
  • Datums vergelijk je met < en >, net als getallen.

Bibboek (Essential)

Deel 1, op papier. De campusbib vraagt een programma. Dit is hun uitleg:

Elk boek in de bib heeft een titel en een aantal pagina’s. Een boek met meer dan 400 pagina’s noemen we een dik boek. Studenten lenen boeken uit en brengen ze terug. Een boek is uitgeleend of staat in de rekken. Je mag een boek drie weken houden, een dik boek een week langer.

  1. Onderlijn de zelfstandige naamwoorden. Welke ervan wordt de klasse die je in deel 2 schrijft, en hoe noem je ze?
  2. Maak een lijstje van wat een boek moet kunnen of weten. Zeg per item of het een property of een methode wordt. Is het een property, welke soort dan: een auto-property, een full property met controle, een read-only property die rekent, of een property die de buitenwereld enkel mag lezen?

Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel gebruikt, dan verschijnt de oplossing hier vanzelf.

Deel 2, in code. Schrijf de klasse Boek met:

  • Titel (string): auto-property met beginwaarde "Zonder titel".
  • Paginas (int): full property. Enkel een waarde groter dan 0 wordt aanvaard. Een nieuw boek heeft 1 pagina.
  • IsDik (bool): read-only, true als het boek meer dan 400 pagina’s heeft.
  • StandaardTermijn (int): read-only auto-property met waarde 3: public int StandaardTermijn { get; } = 3;
  • UitleenTermijn (int): read-only. Voor een dik boek is dat de standaardtermijn plus 1 week, anders de standaardtermijn.
  • IsUitgeleend (bool): auto-property met private set.
  • LeenUit(): is het boek al uitgeleend, dan toont de methode [Titel] is al uitgeleend. Anders wordt het boek uitgeleend en toont ze Je mag [Titel] [UitleenTermijn] weken houden.
  • BrengTerug(): het boek staat terug in de rekken.

Testcode. Zet deze code in je Main. Je klasse werkt als je exact deze uitvoer krijgt.

Boek kookboek = new Boek();
kookboek.Titel = "Pasta voor beginners";
kookboek.Paginas = 48;
kookboek.Paginas = -10;

Boek cursus = new Boek();
cursus.Titel = "Het grote boek van C#";
cursus.Paginas = 520;

Console.WriteLine($"{kookboek.Titel}: {kookboek.Paginas} pagina's, dik: {kookboek.IsDik}");
Console.WriteLine($"{cursus.Titel}: {cursus.Paginas} pagina's, dik: {cursus.IsDik}");

kookboek.LeenUit();
cursus.LeenUit();
cursus.LeenUit();
cursus.BrengTerug();
cursus.LeenUit();
Pasta voor beginners: 48 pagina's, dik: False
Het grote boek van C#: 520 pagina's, dik: True
Je mag Pasta voor beginners 3 weken houden.
Je mag Het grote boek van C# 4 weken houden.
Het grote boek van C# is al uitgeleend.
Je mag Het grote boek van C# 4 weken houden.

Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel gebruikt, dan verschijnt de oplossing hier vanzelf.

  • De zelfstandige naamwoorden in een opgave zijn je kandidaat-klassen. Een klasse krijgt een naam in het enkelvoud.
  • Alle soorten properties kunnen naast elkaar in één klasse staan. Kies telkens de eenvoudigste die volstaat: een auto-property, tenzij er een controle of een berekening nodig is.
  • IsDik en UitleenTermijn bewaren niets: verander je het aantal pagina’s, dan kloppen ze meteen mee.

Persoon aan de fuifdeur (Essential)

Je staat aan de deur van de TD van je studentenclub. Wie nog geen 18 is, mag niet binnen. Om dat te controleren heb je eerst een klasse Persoon nodig.

Deel 1: de klasse

  • Klassenaam: Persoon
  • Properties:
    • Voornaam (string): auto-property.
    • Achternaam (string): auto-property.
    • GeboorteDatum (DateTime): full property. De instantievariabele krijgt als beginwaarde DateTime.Today.
      • Controle in de set: de datum moet tussen 1 januari 1900 en vandaag liggen, beide grenzen inbegrepen.
      • Bij een ongeldige datum: de geboortedatum wordt vandaag.
  • Methoden:
    • BerekenLeeftijd(): geeft de leeftijd in jaren (int) terug, op basis van vandaag en de geboortedatum. Is de verjaardag dit jaar nog niet geweest, dan is de persoon een jaar jonger dan het verschil in jaartallen.

Testcode. Zet deze code in je Main. Je klasse werkt als je exact deze uitvoer krijgt, op welke dag je ze ook uitvoert.

Persoon jana = new Persoon();
jana.Voornaam = "Jana";
jana.GeboorteDatum = DateTime.Today.AddYears(-18);

Persoon mo = new Persoon();
mo.Voornaam = "Mo";
mo.GeboorteDatum = DateTime.Today.AddYears(-18).AddDays(1);

Persoon tijdreiziger = new Persoon();
tijdreiziger.Voornaam = "Marty";
tijdreiziger.GeboorteDatum = DateTime.Today.AddDays(1);

Persoon overgrootmoeder = new Persoon();
overgrootmoeder.Voornaam = "Maria";
overgrootmoeder.GeboorteDatum = new DateTime(1899, 12, 31);

Persoon grens = new Persoon();
grens.Voornaam = "Jozef";
grens.GeboorteDatum = new DateTime(1900, 1, 1);

Console.WriteLine($"{jana.Voornaam}: {jana.BerekenLeeftijd()} jaar");
Console.WriteLine($"{mo.Voornaam}: {mo.BerekenLeeftijd()} jaar");
Console.WriteLine($"{tijdreiziger.Voornaam}: {tijdreiziger.BerekenLeeftijd()} jaar");
Console.WriteLine($"{overgrootmoeder.Voornaam}: {overgrootmoeder.BerekenLeeftijd()} jaar");
Console.WriteLine($"{grens.Voornaam}: geboren in {grens.GeboorteDatum.Year}");
Jana: 18 jaar
Mo: 17 jaar
Marty: 0 jaar
Maria: 0 jaar
Jozef: geboren in 1900

Jana wordt vandaag 18, Mo morgen.

Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel gebruikt, dan verschijnt de oplossing hier vanzelf.

Deel 2: aan de deur

Schrijf een Main die de voornaam en de geboortedatum van een gast vraagt (in de vorm d/m/jjjj), er een Persoon mee maakt en zegt of die binnen mag.

Voornaam?
>Mo
Geboortedatum (d/m/jjjj)?
>14/6/2012
Sorry Mo, je bent nog geen 18. Geen TD vanavond.
Voornaam?
>Jana
Geboortedatum (d/m/jjjj)?
>3/2/2001
Welkom op de TD, Jana!

Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel gebruikt, dan verschijnt de oplossing hier vanzelf.

  • Datums vergelijk je met <, >, <= en >=, net als getallen. new DateTime(1900, 1, 1) maakt de grens.
  • De leeftijd is niet gewoon het verschil in jaartallen: je moet ook kijken of de verjaardag dit jaar al geweest is. Het aantal dagen door 365 delen klopt niet door de schrikkeljaren.
  • De controle staat in de set. Ook een tijdreiziger in de testcode komt er niet langs.

Verjaardag

Doel: Bereken hoelang het nog duurt tot je volgende verjaardag.

Vereisten:

  • Vraag de gebruiker zijn verjaardag in de vorm dag/maand, bv. 18/3. Lees die in met DateTime.Parse en de Belgische cultuur: je krijgt dan die datum in het huidige jaar.
  • Is die datum dit jaar al voorbij, dan is de volgende verjaardag volgend jaar.
  • Gebruik DateTime en TimeSpan.
  • Toon:
    1. hoeveel dagen het nog duurt;
    2. op welke dag van de week (bv. maandag) de volgende verjaardag valt.

Tip voor de dagnaam: DayOfWeek geeft de naam in het Engels. Een Nederlandse naam krijg je zo:

System.Globalization.CultureInfo belgisch = new System.Globalization.CultureInfo("nl-BE");
string dagNaam = belgisch.DateTimeFormat.GetDayName(datum.DayOfWeek);

Voorbeeld, uitgevoerd op 10 oktober 2026:

Wanneer verjaar je (d/m, bv 18/3)?
>20/5
Je bent over 222 dagen jarig, op een donderdag.

Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel gebruikt, dan verschijnt de oplossing hier vanzelf.

  • Zonder nl-BE leest een pc met Engelse instellingen 20/5 niet (de 20e maand bestaat niet) en 11/9 als 9 november.
  • verjaardag.Year = 2027; compileert niet: de properties van DateTime zijn read-only. AddYears geeft een nieuwe datum terug, en die bewaar je opnieuw in verjaardag.
  • Je rekent met DateTime.Today en niet met DateTime.Now. Anders telt het uur van vandaag mee en kom je een dag te kort.

Zaalvoetbal op de campus (Essential)

Je hogeschool organiseert een zaalvoetbalcompetitie, en jouw ploeg wil haar spelers in een programma bijhouden.

Deel 1: alles met auto-properties

  • Enum: Positie, met de waarden Doelman, Verdediger, Middenvelder en Aanvaller.
  • Klasse: Voetballer
  • Properties, alle vier als auto-property:
    • Naam (string)
    • Rugnummer (int)
    • Positie (Positie): de property heeft dezelfde naam als de enum, dat mag.
    • IsKapitein (bool)
  • Methoden:
    • StelIn(string naam, int rugnummer, Positie positie, bool isKapitein): stelt alle properties in.
    • SchietOpDoel(): toont [Naam] schiet op doel!
    • MaakOvertreding(): toont [Naam] krijgt een gele kaart.

Liever een andere sport? Dat mag, als je klasse ook vier eigenschappen heeft, waarvan één een enum, en twee acties.

Testcode deel 1.

Voetballer jonas = new Voetballer();
jonas.StelIn("Jonas", 10, Positie.Aanvaller, true);

Voetballer amira = new Voetballer();
amira.StelIn("Amira", 1, Positie.Doelman, false);

Console.WriteLine($"{jonas.Naam}: nummer {jonas.Rugnummer}, {jonas.Positie}, kapitein: {jonas.IsKapitein}");
Console.WriteLine($"{amira.Naam}: nummer {amira.Rugnummer}, {amira.Positie}, kapitein: {amira.IsKapitein}");
jonas.SchietOpDoel();
amira.MaakOvertreding();
Jonas: nummer 10, Aanvaller, kapitein: True
Amira: nummer 1, Doelman, kapitein: False
Jonas schiet op doel!
Amira krijgt een gele kaart.

Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel gebruikt, dan verschijnt de oplossing hier vanzelf.

Deel 2: de competitie stelt een regel

Een rugnummer moet tussen 1 en 99 liggen. Een auto-property kan dat niet controleren, dus zet je enkel Rugnummer om naar een full property:

  1. Klik in Visual Studio op Rugnummer, klik vooraan op de schroevendraaier en kies Convert to full property.
  2. Visual Studio schrijft de property met =>-tekens. Zet ze om naar de vorm met get en set tussen accolades die je uit het boek kent, of pas eerst de instelling aan die in Auto-properties staat.
  3. Schrijf de controle in de set: buiten 1 tot en met 99 blijft de oude waarde staan. Een nieuwe speler heeft rugnummer 1.

StelIn moet die controle ook volgen. Laat StelIn dus via de property gaan, niet rechtstreeks naar de instantievariabele.

Testcode deel 2.

Voetballer jonas = new Voetballer();
jonas.StelIn("Jonas", 10, Positie.Aanvaller, true);
jonas.Rugnummer = 0;

Voetballer amira = new Voetballer();
amira.StelIn("Amira", 123, Positie.Doelman, false);

Console.WriteLine($"{jonas.Naam}: nummer {jonas.Rugnummer}, {jonas.Positie}, kapitein: {jonas.IsKapitein}");
Console.WriteLine($"{amira.Naam}: nummer {amira.Rugnummer}, {amira.Positie}, kapitein: {amira.IsKapitein}");
Jonas: nummer 10, Aanvaller, kapitein: True
Amira: nummer 1, Doelman, kapitein: False

Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel gebruikt, dan verschijnt de oplossing hier vanzelf.

  • Je begint met auto-properties en zet er enkel een om naar een full property als er een controle nodig is.
  • Omdat StelIn al via de properties werkte, hoef je er in deel 2 niets aan te veranderen. Schrijft StelIn rechtstreeks naar de instantievariabele rugnummer, dan omzeilt het de nieuwe controle en krijgt Amira nummer 123.
  • Een enum maakt van de positie een vaste keuze: "aanvaler" met een typfout kan niet meer.

Dubbel zes

Spelletjesavond op kot. Je kotgenoot beweert dat hij “bijna altijd” dubbel zes gooit. Tijd om dat na te rekenen.

Specificaties:

  • Klassenaam: Dobbelsteen
  • Waarde (int): auto-property met private set, beginwaarde 1.
  • Werp(Random generator): geeft Waarde een willekeurig getal van 1 tot en met 6, gemaakt met de generator die je meekrijgt.

Je programma heeft maar één generator nodig. De klasse maakt dus zelf geen Random aan: Main maakt er één en geeft die bij elke worp mee.

Schrijf daarna een Main die:

  1. één Random en twee dobbelstenen maakt, ze één keer werpt en beide waarden toont;
  2. daarna 1000 keer beide dobbelstenen werpt en telt hoe vaak het dubbel zes is;
  3. dat aantal en het percentage toont, met één cijfer na de komma.

Voorbeeld (bij jou komen er andere getallen uit; gemiddeld is het ongeveer 28 keer):

Eerste worp: 5 en 3
Dubbel zes: 31 keer op 1000 worpen (3,1%)

Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel gebruikt, dan verschijnt de oplossing hier vanzelf.

  • Twee objecten van dezelfde klasse, elk met hun eigen Waarde.
  • Main kan de waarde lezen, maar niet zelf op 6 zetten: enkel Werp mag dat, dankzij de private set. Valsspelen gaat niet.
  • Next(1, 7) geeft 1 tot en met 6: de bovengrens telt niet mee.
  • Beide dobbelstenen gebruiken dezelfde Random uit Main: één generator voor je hele programma, zoals in Random getallen genereren. Een methode kan dus ook een object als parameter krijgen. Wat daar achter de schermen gebeurt, zie je in hoofdstuk 10.

De Campingmanager: “Het Nullpointerke” (Final Essentials)

Scenario: Je bent zojuist aangenomen als lead developer voor Camping “Het Nullpointerke”. De eigenares, Gerda, doet haar boekingen momenteel nog op bierviltjes, maar sinds de doorbraak van “Glamping” verliest ze het overzicht. Ze heeft vooral problemen met gasten die bij het uitchecken niet genoeg geld blijken te hebben, en ze vergeet vaak de seniorenkorting toe te passen (wat tot boze bejaarden aan de receptie leidt).

Aan jou de taak om een digitaal boekingssysteem te bouwen dat deze problemen oplost.

Potloodtekening: de robot zit aan de receptie van een camping met een stapel bierviltjes, het stokmannetje komt aan met een rugzak.

Doel: Ontwerp een klasse Boeking die fungeert als de digitale receptioniste. De klasse moet invoer streng controleren (Gerda houdt van orde), prijzen berekenen op basis van luxe-niveau, en controleren of de gast wel kan betalen voordat de boeking definitief wordt.

Specificaties:

  1. De Accommodatie (Enum)
    • Definieer een enum VerblijfType met opties: Tentplek (basic), Stacaravan (comfort), en LuxeChalet (voor de echte IT-managers).
  2. De Boeking (Klasse)
    • Klassenaam: Boeking
    • Properties (met controle):
      • Hoofdboeker (string): De naam van de gast. Mag niet leeg zijn. Als iemand een lege naam opgeeft, noem je hem “Onbekende Gast”. Dat is ook de beginwaarde.
      • GeboorteDatum (DateTime): Mag niet in de toekomst liggen. (Tijdreizigers worden niet toegelaten). Indien fout: stel in op vandaag.
      • HuidigBudget (double): De inhoud van de portemonnee van de gast. Mag niet negatief zijn: een negatieve waarde wordt geweigerd en de oude waarde blijft staan (geen schulden bij aankomst!).
      • Type (VerblijfType): Het gekozen verblijf.
      • CheckInDatum (DateTime): read-only auto-property met als beginwaarde vandaag. (We boeken enkel last-minute).
    • Methoden:
      • BerekenLeeftijd() (returntype: int): een private hulpmethode die de leeftijd van de gast berekent, zoals in Persoon aan de fuifdeur. De buitenwereld heeft ze niet nodig, enkel de klasse zelf.

      • BerekenTotaalPrijs(int aantalNachten) (returntype: double):

        • Basisprijzen: Tentplek = €25, Stacaravan = €50, LuxeChalet = €95 (prijzen per nacht).
        • Korting: Gerda heeft een zwak voor gepensioneerden. Is de gast ouder dan 60 jaar? Geef dan 15% korting op het totaalbedrag.
      • BevestigBoeking(int aantalNachten) (returntype: void):

        • Dit is de grote finale. Roep BerekenTotaalPrijs aan om te weten wat het kost.
        • Check: Heeft de gast genoeg HuidigBudget?
        • Scenario A (Genoeg geld):
          • Trek het bedrag af van het HuidigBudget.
          • Bereken de uitcheck-datum (CheckInDatum + aantal nachten).
          • Toon in de console: “Boeking geslaagd voor [Naam]! U checkt uit op [Datum]. Restbudget: €[Bedrag]”.
        • Scenario B (Te weinig geld):
          • Toon in de console: “Helaas [Naam], dit kost €[Prijs], maar u heeft slechts €[Budget]. Ga eerst langs de bankautomaat.”

Het €-teken verschijnt pas in de console met Console.OutputEncoding = System.Text.Encoding.UTF8; als eerste lijn in Main (zie hoofdstuk 3).

Voorbeeldgebruik (in je Main):

Console.OutputEncoding = System.Text.Encoding.UTF8;

// Scenario: Opa Pol wil 5 nachten in een chalet, maar is zijn portefeuille vergeten.
Boeking boeking1 = new Boeking();
boeking1.Hoofdboeker = "Pol";
boeking1.GeboorteDatum = new DateTime(1955, 3, 12); // Pol is ouder dan 60
boeking1.Type = VerblijfType.LuxeChalet;
boeking1.HuidigBudget = 200; // Oei, dat is krap voor een chalet

Console.WriteLine("--- Poging 1 ---");
boeking1.BevestigBoeking(5);

// Pol vindt 300 euro in zijn andere broekzak
Console.WriteLine("\n--- Poging 2 (met meer geld) ---");
boeking1.HuidigBudget += 300;
boeking1.BevestigBoeking(5);

Uitgevoerd op 10 oktober 2026 (de uitcheckdatum hangt af van de dag waarop je het uitvoert):

--- Poging 1 ---
Helaas Pol, dit kost €403,75, maar u heeft slechts €200. Ga eerst langs de bankautomaat.

--- Poging 2 (met meer geld) ---
Boeking geslaagd voor Pol! U checkt uit op 15/10/2026. Restbudget: €96,25

Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel gebruikt, dan verschijnt de oplossing hier vanzelf.