Constructors in C#
Inleiding
Je object is geboren uit een klasse en je object gaat nu de wijde wereld in om van alles te ontdekken en te doen. Een constructor is een methode dat automatisch wordt gestart bij de instantiatie van een object. Als rechtgeaarde ouder wil je dat je objecten een zo goed mogelijke start krijgen en constructors kunnen daarbij een handje helpen. De naam van de constructor is gelijk aan de naam van de klasse en als zodanig herkenbaar.
Deze post gaat verder met het voorbeeld dat in de post over object oriëntatie is besproken. Het verdient de aanbeveling eerst de desbetreffende post te lezen alvorens verder te gaan met deze post.
Constructor
In het eerdere voorbeeld werd op onderstaande manier een object geïnstantieerd waarbij aan de constructor twee waarden werden meegegeven. De constructor zorgt er dan voor dat via een aantal backing variables de object eigenschappen hun waarden krijgen.
// klasse definitie class Auto
{
// -- Backing variables - fields -- private string _merk;
private int _milieusticker;
private string _vervuilingsgraad; // Constructor
// (naam is hetzelfde als de naam van de klasse) public Auto( string merk, int milieusticker)
{
_merk = merk;
_milieusticker = milieusticker;
_vervuilingsgraad = OverJeAuto(milieusticker);
}
. . } // Creëer object, instantieer met 2 parameters Auto mijnAuto = new Auto( merk: "GHB (GuanggongHunnenburgBetrieb)" , milieusticker: ( int )Kleur.Grijs); // En we hebben.. Console.WriteLine( "Je bent in het trotse bezit van:" ); Console.WriteLine( "- een {0}." , mijnAuto.Merk); Console.WriteLine( "- En de Milieusticker van je bolide is {0}." + Environment.NewLine, (Kleur)mijnAuto.MilieuSticker); . . |
Constructor Chaining
Stel dat je bij het instantiëren alleen maar een merk hoefde op te geven en dat op een kwade dag het opgeven van de kleur van je milieusticker opeens verplicht wordt bij het instantiëren. Hoe vang je dan de situatie af dat bij het instantiëren geen milieusticker kleur wordt meegegeven of dat bij het instantiëren helemaal niks wordt meegegeven?
Het kan zelfs tot foutmeldingen leiden als de klasse in een Class Library zit en andere programma’s functies uit die Class Library aanroepen en nog steeds op de oude manier met maar één parameter instantiëren. Het verplicht moeten instantiëren met twee parameters wordt dan een “breaking change”.
Je kunt situaties als hierboven afvangen met Constructor Chaining. Je ziet hieronder een drietal constructors. Er is een constructor met twee parameters, een constructor met één parameter en een constructor zonder parameters:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | // klasse definitie class Auto
{
. . // Een Constructor met twee parameters public Auto( string merk, int milieusticker)
{
_milieusticker = milieusticker;
_merk = merk;
_vervuilingsgraad = OverJeAuto(milieusticker);
} // Een Constructor met één parameter public Auto( string merk) : this (merk, ( int )Kleur.Groen) { } // Een Constructor zonder parameters public Auto() : this ( "GuanggongHunnenburgBetrieb" , ( int )Kleur.Groen) { }
. . } |
De this keyword zorgt ervoor dat wordt “doorgechained” naar de constructor met de meeste parameters waardoor je alleen maar in de constructor met de meeste parameters dingen hoeft te doen met backing variables.
Onze “GHB GuanggongHunnenburgBetrieb” auto in ons voorbeeld gaf vanwege de grijze milieusticker een wat gênante waarde voor de vervuilingsgraad (ultra vervuilend).
Met constructor chaining kunnen we het één en ander in ons voordeel laten doen uitslaan door een groene milieusticker (milieuvriendelijkst) als default waarde mee te geven indien geen kleur wordt meegegeven bij het instantiëren. We krijgen, als we bijvoorbeeld met maar één parameter instantiëren:
Auto mijnAuto = new Auto(merk: "GHD (GuanggongHunnenburgBetrieb)"); |
dit resultaat waarbij de GHD GuanggongHunnenburgBetrieb auto opeens enorm mileuvriendelijk is:
Je bent in het trotse bezit van: - een GHD (GuanggongHunnenburgBetrieb). - En de Milieusticker van je bolide is Groen. Over de vervuilingsgraad van je auto: - Je voertuig is momenteel de milieuvriendelijkste. |
We worden zo niet geconfrontreerd met de gênante situatie dat we een milieusticker kleur moeten opgeven. Op die manier liegen we niet eens, we verzwijgen gewoon dingen, maar we liegen doen we nog steeds niet, toch?
Slot
In deze post hebben we het gehad over constructors en constructor chaining. In de post over de GAC en de DLL Hell hadden we het gehad over meerdere assembly versies die naast elkaar in de GAC moeten worden gezet. Dit om ervoor te zorgen dat dingen goed blijven gaan als assemblies op een oude manier door programma’s worden aanroepen.
Met constructor chaining hoef je, voor wat betreft het instantiëren, geen meerdere versies naast elkaar aan te houden indien bij het instantiëren extra parameters nodig zijn. Je kunt via constructor chaining default waardes instellen voor datgene wat ontbreekt. Het blijft dan goed gaan als een object wordt geïnstantieerd zonder die extra parameter(s) .
We hebben het één en ander geïllustreerd met onze GuanggongHunnenburgBetrieb auto door default een groene milieusticker toe te kennen als bij het instantiëren de kleur van de mileusticker niet wordt opgeven.
Hopelijk ben je met deze posting weer wat wijzer geworden en ik hoop je weer terug te zien in één van mijn volgende blog posts. Wil je weten wat ik nog meer over C# heb geschreven? Hit the C# button…
Voorbeeldprogramma
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | using System; public enum Kleur { Groen, Paars, Geel, Oranje, Rood, Grijs } class Auto { // Backing variables - fields private string _merk; private int _milieusticker; private string _vervuilingsgraad; // Property Merk public string Merk { get { return _merk; } set { _merk = value; } } // Property MilieuSticker public int MilieuSticker { get { return _milieusticker; } set { _milieusticker = value; } } // Property Vervuilingsgraad public string Vervuilingsgraad { get { return _vervuilingsgraad; } } // Constructor // als 2 parameters zijn opgegeven public Auto( string merk, int milieusticker) { _milieusticker = milieusticker; _merk = merk; _vervuilingsgraad = OverJeAuto(milieusticker); } // Constructor // Als 1 parameter is opgegeven public Auto( string merk) : this (merk, ( int )Kleur.Groen) { } // Constructor // Als geen parameters zijn opgegeven public Auto() : this ( "Onbekend merk" , ( int )Kleur.Groen) { } // Methode OverjeAuto public string OverJeAuto( int kleur) { string resultaat = "" ; switch (kleur) { case ( int )Kleur.Groen: resultaat = "- Je voertuig is momenteel de milieuvriendelijkste."; break ; case ( int )Kleur.Paars: resultaat = "- Je voertuig zit iets onder de norm, maar voldoet."; break ; case ( int )Kleur.Geel: resultaat = "- Je voertuig is al wat ouder en iets minder schoon."; break ; case ( int )Kleur.Oranje: resultaat = "- Je voertuig is tamelijk oud en relatief vervuilend."; break ; case ( int )Kleur.Rood: resultaat = "- Je voertuig zeer vervuilend!" ; break ; case ( int )Kleur.Grijs: resultaat = "- Je voertuig is ultra vervuilend!!" ; break ; default : resultaat = "- Geen gegevens bekend over de vervuilingsgraad."; break ; } return resultaat; } } class MainClass { public static void Main( string [] args) { // Instantieer Auto mijnAuto = new Auto( merk: "GHB (GuangzGongHunnenburgBetrieb)" ); // En we hebben.. Console.WriteLine( "Je bent in het trotse bezit van:" ); Console.WriteLine( "- een {0}." , mijnAuto.Merk); Console.WriteLine( "- En de Milieusticker van je bolide is {0}." + Environment.NewLine, (Kleur)mijnAuto.MilieuSticker); Console.WriteLine( "Over de vervuilingsgraad van je auto:" + Environment.NewLine + "{0}" + Environment.NewLine, mijnAuto.Vervuilingsgraad); } } |