Null en NullReferenceException
Zoals nu duidelijk is bevatten referentievariabelen steeds een referentie naar een object. Maar wat als we dit schrijven:
Dit zal een fout geven. Het object stud1
bevat namelijk nog geen referentie. Maar wat dan wel?
Deze variabele bevat de waarde null
. Net zoals bij value types die een default waarde hebben als je er geen geeft (bv. 0 bij een int
), zo bevatten reference type variabelen altijd null
als standaardwaarde.
null
is een waarde die je kan toekenen aan eender welk reference type. Je doet dit om aan te geven dat er nog geen referentie naar een effectief object in de variabele staat. Je kan dus ook op deze waarde testen.
Van zodra je een referentie naar een object (een bestaand of eentje dat je net met new
hebt aangemaakt) aan een reference type variabele toewijst (met de =
operator) zal de null
waarde uiteraard overschreven worden.
Merk op dat de GC enkel op de heap werkt. Indien er in de stack dus een variabele de waarde null
heeft zal de GC deze nooit verwijderen!
NullReferenceException
Een veel voorkomende foutboodschap tijdens de uitvoer van je applicatie is een NullReferenceException
. Deze zal optreden wanneer je code een object probeert te benaderen wiens waarde null
is (een onbestaand object met andere woorden).
Laten we dit eens simuleren:
Dit zal resulteren in een foutboodschap in VS bij de lijn die de uitzondering detecteert: "System.NullReferenceException: 'Object reference not set to an instance of an object'. stud1 was null".
We moeten in dit voorbeeld expliciet = null
plaatsen daar Visual Studio slim genoeg is om je te waarschuwen voor eenvoudige potentiële NullReference fouten en je code anders niet zal compileren.
NullReferenceException voorkomen
Objecten die niet bestaan zullen altijd null
hebben. Uiteraard kan je niet altijd al je code uitvlooien waar je misschien vergeten bent een object met new
aan te te maken.
Voorts kan het ook soms by design zijn dat een object voorlopig null
is.
Gelukkig kan je controleren of een object null
is als volgt:
Verkorte null controle notatie
Vaak moet je dit soort code schrijven:
Op die manier voorkom je een NullReferenceException
. Het is uiteraard omslachtig om steeds die check te doen. Je mag daarom ook schrijven:
Het vraagteken direct na het object geeft aan: "Gelieve de code na dit vraagteken enkel uit te voeren indien het object voor het vraagteken niét null is".
Bovenstaande code zal dus gewoon een lege lijn op scherm plaatsen indien stud1
effectief null
is, anders komt de naam op het scherm.
Return null
null
Uiteraard mag je ook expliciet null
teruggeven als resultaat van een methode. Stel dat je een methode hebt die in een array een bepaald object moet zoeken. Wat moet de methode teruggeven als deze niet gevonden wordt? Inderdaad, we geven dan null
terug.
Volgende methode zoekt in een array van studenten naar een student met een specifieke naam en geeft deze terug als resultaat. Enkel als de hele array werd doorlopen en er geen match is wordt er null
teruggegeven (de werking van arrays van objecten wordt later besproken):
Bevallen in code met ouders
Tijd om het voorbeeld van de voortplanting der mensch er nog eens bij te nemen. Beeld je nu in dat we dichter naar de realiteit willen gaan (meestal toch het doel van OOP) en de baby eigenschappen van beide willen ouders geven. Stel dat mensen een maximum lengte hebben die ze genetisch kunnen halen, aangeduid via een auto-property MaxLengte
. De maximale lengte van een baby is steeds de lengte van de grootste ouder (in de echte genetica is dat natuurlijk niet).
De klasse Mens
breiden we uit naar:
Mooi toch?!
Om het nu volledig te maken zullen we er voor zorgen dat enkel een vrouw kan voortplanten. Voorts kan ze zich enkel voortplanten met behulp van een van een man (merk op dat OOP als doel heeft de realiteit te benaderen, maar ook te vereenvoudigen naargelang het probleem).
Veronderstel dat het geslacht via een enumtype (enum Geslachten {Man, Vrouw}
) in een auto-property Geslacht
wordt bewaard. We voegen daarom bovenaan in de PlantVoort
-methode nog een kleine check in én return'n een leeg (null
) object als de voortplanting faalt (we zouden ook een Exception
kunnen opwerpen):
Volgende code produceert nu een kersverse baby:
Hopelijk voel je bij dit voorbeeld hetzelfde enthousiasme als toen we Pong naar OOP omzetten. Probeer voorgaande voorbeeld eens te schrijven met je kennis VOOR je klassen en objecten kende? Doenbaar? Zeker. Veel werk? Dat nog meer. En daar is het ons om te doen: krachtige, makkelijker te onderhouden code leren schrijven!
Last updated