In Visual Basic kunnen procedureparameters bij referentie (ByRef) of bij waarde (ByVal) worden doorgegeven. Dit beïnvloedt of wijzigingen binnen de procedure zich reflecteren op de oorspronkelijke variabele buiten de procedure.
Achtergrond:
In VB.NET worden procedureparameters standaard bij waarde (ByVal) doorgegeven, wat betekent dat een kopie van de waarde wordt doorgegeven. Via ByRef wordt geen kopie doorgegeven, maar een verwijzing naar de originele variabele.
Probleem:
Onjuist gebruik van de doorgeefmethode kan leiden tot fouten — bijvoorbeeld, bij verkeerd gebruik van ByRef kan de procedure variabelen in de aanroepende code onbedoeld wijzigen, of omgekeerd, wijzigingen worden niet behouden.
Oplossing:
ByRef wordt gebruikt wanneer meerdere waarden moeten worden geretourneerd of wanneer de doorgegeven variabele moet worden gewijzigd. ByVal wordt in alle andere gevallen gebruikt ter bescherming tegen ongewenste wijzigingen. Het is uiterst belangrijk om ByRef alleen expliciet aan te geven indien nodig.
Voorbeeld van doorgeven bij waarde en bij referentie:
Sub DoubleValue(ByVal x As Integer) x = x * 2 End Sub Sub DoubleValueByRef(ByRef x As Integer) x = x * 2 End Sub Dim a As Integer = 5 DoubleValue(a) ' a blijft 5 DoubleValueByRef(a) ' a is nu 10
Belangrijke kenmerken:
Wat gebeurt er met het object bij ByRef doorgeven: verandert de verwijzing naar het object?
Antwoord: Als je een object bij ByRef doorgeeft en in de procedure een nieuwe object aan de variabele toewijst, dan zal de oorspronkelijke variabele buiten de procedure ook naar het nieuwe object verwijzen. Bij ByVal kun je de eigenschappen van het object wijzigen, maar je kunt de verwijzing zelf niet verplaatsen — de variabele buiten de procedure blijft hetzelfde.
Sub ChangeRef(ByRef p As Person) p = New Person() With {.Name = "Andere"} End Sub Sub ChangeVal(ByVal p As Person) p.Name = "Veranderd" End Sub Dim pers As New Person With {.Name = "Oorspronkelijk"} ChangeRef(pers) ' pers is nu een nieuw object ChangeVal(pers) ' pers is hetzelfde object, de naam is veranderd
Kan ByRef worden gebruikt om een waarde uit een Function te retourneren?
Antwoord: Nee, ByRef wordt alleen aangegeven bij het doorgeven van parameters, en niet voor de daadwerkelijke retourwaarde van de functie.
Wat als het argument van een array met ByVal is gedeclareerd — kan de inhoud van de array worden gewijzigd?
Antwoord: Ja, omdat in VB.NET een array een referentietype is, en ondanks dat het bij ByVal wordt doorgegeven, wordt de verwijzing gekopieerd, en kunnen de elementen van de array (via dezelfde verwijzing) binnen de procedure worden gewijzigd.
In het team gebruikte een van de ontwikkelaars ByRef in een verwerkingsalgoritme, en wijziging van een waarde in een deel van het programma veranderde onverwachts de toestand van de variabele, waardoor de module niet correct functioneerde.
Voordelen: Sta toe om gegevens te wijzigen zonder de structuur van de retourwaarde te specificeren
Nadelen: Hoge kans op onduidelijke bijeffecten, moeilijk om bugs op te sporen
Parameters worden doorgegeven via ByVal, en het retourneren van meerdere waarden gebeurt via retourstructuren of Tuple, wat het gedrag duidelijk en praktisch maakt.
Voordelen: Makkelijker om de code te lezen en te onderhouden, minder bugs
Nadelen: Soms zijn extra types of structuren nodig om te maken.