Achtergrond
Eigenschappen in Visual Basic stellen gebruikers in staat om de logica voor het verkrijgen en instellen van waarden in te kapselen. Door de introductie van eigenschappen wordt de code leesbaarder en veiliger, waarbij de noodzaak voor directe toegang tot klassevelden wordt geëlimineerd, en het gemakkelijker wordt om validatielogica of berekeningen direct in objecten te integreren.
Probleem
Beginners maken vaak een veld openbaar of gebruiken automatische eigenschappen zonder getter/setter met logica, wat leidt tot schending van encapsulatie of het onvermogen om berekende waarden te implementeren. Een ander probleem is de recursieve aanroep van een eigenschap binnen zichzelf, wat leidt tot StackOverflow.
Oplossing
In Visual Basic wordt een privéveld gedeclareerd, en de eigenschap bevat Get- en Set-blokken met de vereiste logica. Berekende eigenschappen gebruiken alleen Get, waarbij een berekende waarde op basis van privévelden wordt geretourneerd. Binnen het set-blok moet altijd naar het privéveld worden verwezen om eindeloze recursie te voorkomen.
Voorbeeldcode:
Private _prijs As Decimal Private _hoeveelheid As Integer Public Property Totaal As Decimal Get Return _prijs * _hoeveelheid ' berekende eigenschap End Get End Property Public Property Prijs As Decimal Get Return _prijs End Get Set(value As Decimal) If value < 0 Then Throw New ArgumentException("Prijs moet positief zijn") _prijs = value End Set End Property
Belangrijkste kenmerken:
Is het toegestaan om binnen Set Prijs naar de eigenschap Naam te verwijzen, als deze ook is geïmplementeerd via een privéveld?
Ja, het is toegestaan om in het set-blok van de eigenschap Prijs naar een andere eigenschap (bijvoorbeeld Naam) te verwijzen, omdat verwijzingen naar verschillende privévelden geen recursie veroorzaken. Vermijd om naar jezelf te verwijzen: het aanroepen van Prijs binnen Set Prijs zal recursie veroorzaken.
Voorbeeldcode:
Public Property Naam As String Get Return _naam End Get Set(value As String) _naam = value End Set End Property Public Property Prijs As Decimal Get Return _prijs End Get Set(value As Decimal) If Naam Is Nothing Then _naam = "default" _prijs = value End Set End Property
Wat gebeurt er als binnen het Get-blok van een eigenschap deze eigenschap opnieuw wordt aangeroepen?
Dit leidt tot eindeloze recursie en StackOverflow. In het get-blok moet altijd een privéveld worden gebruikt, anders zal de eigenschap zichzelf blijven aanroepen.
Public Property Hoeveelheid As Decimal Get Return Hoeveelheid ' leidt tot eindeloze recursie End Get Set(value As Decimal) _hoeveelheid = value End Set End Property
Is het mogelijk om een eigenschap alleen voor schrijven (WriteOnly) te declareren en wat zijn de risico's?
Er zijn WriteOnly-eigenschappen, maar het is niet aan te raden ze te gebruiken, omdat het object de mogelijkheid verliest om een waarde terug te geven, wat de leesbaarheid en voorspelbaarheid verergert. Als het alleen voor schrijven nodig is, is het beter om de architectuur te heroverwegen.
Private _geheim As String Public WriteOnly Property Geheim As String Set(value As String) _geheim = value ' Kan schrijven, maar niet lezen. End Set End Property
Een programmeur besloot om het veld Prijs openbaar te maken en werkte er direct mee. Hierdoor werd Prijs soms onterecht negatief.
Voordelen:
Nadelen:
Een collega verving Prijs door een eigenschap met een privéveld en validatie in het set-blok, wat foutieve waarden voorkwam.
Voordelen:
Nadelen: