This article has been localized into Dutch by the community.
Constanten (het const keyword)
Tot nu toe hebben we heel wat met variabelen te maken gehad, en zoals de naam al suggereert kunnen variabelen altijd van waarde veranderen. In tegenstelling tot constanten, die in C# gedeclareerd worden middels het keyword const. Als je een constante declareert, moet je er meteen een waarde aan koppelen, en daarna kunnen er GEEN wijzingen meer aangebracht worden. Dit is handig als je een parameter hebt die toch nooit van waarde verandert, en die ook niet per ongeluk door je code gewijzigd kan worden.
Er zijn heel wat constanten in het C# framework zelf gedefinieerd, bijvoorbeeld in de Math class, waar een constante genaamd PI gedefinieerd is:
Console.WriteLine(Math.PI);
Natuurlijk is het interessanter om onze eigen constanten te declareren. Een constante kan gedefinieerd worden als onderdeel van een methode, bijvoorbeeld:
static void Main(string[] args)
{
const int TheAnswerToLife = 42;
Console.WriteLine("The answer to life, the universe and everything: " + TheAnswerToLife);
}
Maar meestal zullen constanten gedeclareerd worden op het niveau van de class, zodat ze gebruikt (maar uiteraard niet veranderd) kunnen worden door alle methoden binnen die class, en afhankelijk van de zichtbaarheid zelfs buiten die class. Een constante gedraagt zich als een statisch onderdeel van die class, wat inhoudt dat je er toegang toe hebt zonder de class te hoeven instantiëren. Met die wetenschap gaan we nu een voorbeeld maken waarbij 2 constanten worden gedefinieerd, een private en een public:
using System;
namespace Constants
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("The fake answer to life: " + SomeClass.TheFakeAnswerToLife);
Console.WriteLine("The real answer to life: " + SomeClass.GetAnswer());
}
}
class SomeClass
{
private const int TheAnswerToLife = 42;
public const int TheFakeAnswerToLife = 43;
public static int GetAnswer()
{
return TheAnswerToLife;
}
}
}
Merk op hoe ik een klasse (SomeClass) gedefinieerd heb met 2 constanten. De eerste is private, wat er voor zorgt dat deze enkel binnen de klasse zelf kan benaderd worden. De andere is public. Dit zorgt ervoor dat binnen de Main code deze constanten anders moeten benaderd worden. De TheFakeAnswerToLife constante kunnen we direct benaderen omdat deze public gedeclareerd is, de private gedeclareerde TheAnswerToLife constante moet we echter benaderen met de GetAnswer() methode.
Welke types kunnen we gebruiken als constante?
Als we een constante declareren moet er ook direct een waarde aan toegekend worden. Deze waarde moet dus ook constant zijn en de compiler moet in staat zijn om de waarde bij het compileren reeds te evalueren. Dit houdt in dat nummers, booleans en strings perfect kunnen gebruikt worden als constante, maar dat bijvoorbeeld een DateTime object niet gebruikt kan worden als constante.
Aangezien de compiler direct de waarde van een constante moet kennen zijn er ook beperkingen in wat je kan doen als je de waarde toekent. Dit zijn voorbeelden van zaken die je WEL kan doen:
const int a = 10;
const float b = a * 2.5f;
const string s1 = "Hello, world!";
const string s2 = s1 + " How are you?";
Je kan daarentegen geen resultaat van een methode of een niet-constant klasselid gebruiken aangezien dit geen constante expressies zijn. Hier een paar voorbeelden van zaken die je NIET kan doen:
// NOT possible:
const int a = Math.Cos(4) * 2;
// Possible:
const string s1 = "Hello, world!";
// NOT possible:
const string s2 = s1.Substring(0, 6) + " Universe";
Het verschil zit in het feit dat de compiler moet weten wat hij kan verwachten wanneer hij de code bereikt. Bij nummers, strings en andere constanten is dit het geval, in tegenstelling tot zaken die hij eerst moet uitvoeren alvorens een waarde te krijgen.
Een alternatief voor constanten: het alleen-lezen veld
Als je op zoek bent naar een iets minder restrictieve versie van een constante kan je misschien het readonly keyword gebruiken. Je kan het niet gebruiken in een methode, maar wel binnen een klasse om een veld te definiëren dat enkel kan gewijzigd worden tijdens de declarative of bij het uitvoeren van de constructor methode van de klasse. Van zodra een object beschikbaar is voor gebruik zal het readonly veld voor altijd dezelfde waarde hebben en kan het niet aangepast worden door de gebruiker. Laat ons dit even proberen:
class SomeClass
{
private readonly DateTime rightNow;
public readonly DateTime later = DateTime.Now.AddHours(2);
public SomeClass()
{
this.rightNow = DateTime.Now;
}
}
We hebben hier 2 readonly velden, het eerste is private, het tweede public. De eerste is gedeclareerd zonder waarde (dit is mogelijk bij een readonly veld) en de tweede krijgt onmiddelijk een waarde toegewezen. Je ziet dat we de DateTime klassen gebruiken als data type en we dus een niet constante waarde toewijzen aan onze velden. We doen dus een aantal zaken die we met een constante niet kunnen doen en toch beschermen we onze velden tegen wijziging door de gebruiker, dit maakt van readonly velden een goed alternatief voor constanten.
Je ziet ook dat ik een waarde toeken aan het rightNow veld in de constructor van de SomeClass klasse. Zoals eerder vermeld is dit het laatste moment waarop je een waarde kan toekennen aan een readonly veld. Daarna, of je nu binnen de klasse bent waarin het readonly veld is gedefinieerd of daarbuiten, zal je een compile error krijgen als je een waarde probeert toe te kennen aan het readonly veld.
Samenvatting
Een constante kan je definiëren binnen een methode of een klasse. Je kan er een waarde in opslaan die door de compiler reeds gekend is bij het compileren en die achteraf niet meer kan gewijzigd worden. Types die vaak gebruikt worden voor constanten zijn integers, floats, strings en booleans. Als je iets meer flexibiliteit zoekt kan je het readonly veld gebruiken zoals hierboven beschreven.