Zie Scherp Scherper - Hoofdstuk 10
Na dit hoofdstuk kan je:
null en de NullReferenceException vermijdennamespace en using situerentry, catch en finallyEen C#-programma krijgt twee geheugens:
| Value types | Reference types | |
|---|---|---|
| Inhoud | de waarde zelf | een verwijzing naar de data |
| Locatie | stack | heap |
| Default | 0, false, … |
null |
= kopieert |
de waarde | het adres |
De heap is de grote speelplaats; de stack het kleine, snelle bankje ernaast.
= kopieert de waarde. Een methode krijgt een kopie:
new Student() maakt het object in de heap en geeft het adres terugstud staat in de stackstud bewaardOpmerking
Zonder new is stud nog null: een lege doos, zonder verwijzing.
Een object kan groot zijn, een echte “menhir” in het geheugen. Een referentie is maar een klein adres dat ernaar wijst.
Tip
Obelix sleurt niet met elke menhir mee: hij verlegt gewoon het bordje dat ernaar wijst. Net zo werkt je computer met objecten.
Objecten in de heap waar geen referentie meer naar wijst, worden door de GC opgeruimd:
Waarschuwing
Roep nooit zelf GC.Collect() op. De GC kiest zelf het beste moment; jij maakt het meestal net trager.
string is een reference type, maar gedraagt zich vaak als een value type omdat het immutable is:
Tip
Methoden op een string geven steeds een nieuwe string terug. Vergeet je de toewijzing (naam.ToUpper();), dan verandert er niets.
Objecten gaan by reference naar een methode. Aanpassingen werken op het origineel:
Opmerking
Een methode mag ook een object teruggeven (return new Meting();), bijvoorbeeld PlantVoort() die een nieuw Mens-object oplevert.
Een methode kan een nieuw object teruggeven, met je eigen regels:
Tip
Jij bepaalt de regels van je objecten: een baby wordt nooit langer dan de grootste ouder, en enkel een Mens met de juiste eigenschappen kan KrijgKind aanroepen.
Waarschuwing
“Object reference not set to an instance of an object”: de beruchte NullReferenceException. Je gebruikt een object dat nog niet met new is gemaakt.
?. (null-conditional) voert de code enkel uit als het object niet null isnull teruggeven (bv. “niet gevonden”)Opmerking
Groene kronkellijntjes rond null? Dat is de nullable reference types-functie. Die behandelen we bewust nog niet; je mag ze voorlopig negeren.
Een namespace voorkomt naamconflicten tussen klassen:
De volledige naam is MyEpicGame.Monster, dus een Monster uit een ander project (NietZoEpicGame.Monster) botst er niet mee.
De politie, uw vriend! Vraag je “waar is de Kerkstraat?”, dan vragen wij eerst: in welke gemeente?
Een namespace is net die gemeentenaam: ze laat toe een klasse (de straat) zonder verwarring te identificeren.
using voor jeColorful.Console)Uitzonderingen liggen vaak buiten je controle:
null-object)Tip
Een onafgehandelde exception toont een joekel van een foutmelding en sluit je programma af. Exception handling laat je netjes reageren, zonder een woud aan if-checks.
Vroeger checkte je elke stap met if’s, diep genest:
Waarschuwing
Onleesbaar en foutgevoelig. try/catch scheidt de gewone flow netjes van de foutafhandeling.
try-blok staat code die kan mislukkencatch-blok vangt de uitzondering op en laat je programma netjes verder werkenJe kan zelf een uitzondering opwerpen:
Opmerking
Bij een throw klimt de uitvoering omhoog door de methode-aanroepen (stack unwinding) tot er een passend catch-blok klaarstaat. Daarom telt de plaats van je try/catch.
Exceptions vormen een hiërarchie: FormatException is óók een Exception.
Waarschuwing
Specifiek eerst, algemeen laatst. Zet je catch (Exception) bovenaan, dan compileert je code niet: het zou alles al opvangen.
Message, StackTrace, TargetSite, … geven info over de fout.
Belangrijk
Stuur deze info niet zomaar naar de gebruiker: ze kan gevoelige details bevatten die kwaadwillige gebruikers misbruiken.
Tip
Een leeg catch-blok is een anti-pattern: je verbergt bugs in plaats van ze op te lossen.
Het finally-blok draait altijd: of er nu een exception was of niet. Samen vormen try, catch en finally de drie-eenheid van exception handling.
De plaats van je try/catch bepaalt dus hoe je programma op fouten reageert.
= kopieert bij objecten het adres, niet het object: pas op voor de alias-valnew niet (null!)namespace en using ordenen je klassen en voorkomen naamconflictentry/catch/finally vangt uitzonderingen op: specifiek eerst, algemeen laatstTip
Volgende halte: gevorderde klasseconcepten, met constructors en static.
Kennisclips
Dezelfde concepten uit dit hoofdstuk, maar dan in andere talen. Handig om later code in Python of JavaScript te leren lezen.
C# heeft een GC. In C++ beheer je geheugen zelf met new en delete:
Vergeet je delete, dan lek je geheugen (memory leak). De C#-GC neemt dat risico van je over.
Python noemt null gewoon None:
JavaScript heeft er zelfs twee: null (bewust leeg) én undefined (nooit toegekend):
Python kent ook exceptions, maar catch heet er except:
De taal C heeft geen exceptions: je checkt zelf na elke aanroep een foutcode:
Een handige samenvattende poster (Opgelet: gemaakt m.b.v. ChatGPT Image Gen 2).