Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Op deze pagina vindt u enkele veelvoorkomende problemen die kunnen optreden bij het werken met procedures.
Een matrixtype retourneren vanuit een functieprocedure
Als een Function procedure een matrixgegevenstype retourneert, kunt u de Function naam niet gebruiken om waarden op te slaan in de elementen van de matrix. Als u dit probeert te doen, interpreteert de compiler deze als een aanroep naar de Function. In het volgende voorbeeld worden compilerfouten gegenereerd:
Function AllOnes(n As Integer) As Integer()
For i As Integer = 1 To n - 1
' The following statement generates a COMPILER ERROR.
AllOnes(i) = 1
Next
' The following statement generates a COMPILER ERROR.
Return AllOnes()
End Function
De instructie AllOnes(i) = 1 genereert een compilerfout omdat deze lijkt aan te roepen AllOnes met een argument van het verkeerde gegevenstype (een scalaire Integer waarde in plaats van een Integer matrix). De instructie Return AllOnes() genereert een compilerfout omdat deze zonder argument lijkt aan te roepen AllOnes .
Juiste benadering: Als u de elementen van een matrix wilt wijzigen die moet worden geretourneerd, definieert u een interne matrix als een lokale variabele. In het volgende voorbeeld wordt zonder fouten gecompileerd:
Function AllOnes(n As Integer) As Integer()
Dim iArray(n - 1) As Integer
For i = 0 To n - 1
iArray(i) = 1
Next
Return iArray
End Function
Argument niet gewijzigd door procedureoproep
Als u van plan bent een procedure toe te staan om een programmeerelement te wijzigen dat aan een argument in de aanroepcode is gekoppeld, moet u deze doorgeven via referentie. Maar een procedure heeft toegang tot de elementen van een verwijzingstypeargument, zelfs als u deze doorgeeft op waarde.
Onderliggende variabele. Als u wilt toestaan dat de procedure de waarde van het onderliggende variabele-element zelf vervangt, moet de procedure de parameter ByRef declareren. Bovendien mag de aanroepende code het argument niet tussen haakjes insluiten, omdat dat het
ByRefdoorgevende mechanisme zou overschrijven.Verwijzingstype-elementen. Als u een parameter ByVal declareert, kan de procedure het onderliggende variabele-element zelf niet wijzigen. Als het argument echter een verwijzingstype is, kan de procedure de leden wijzigen van het object waarnaar het verwijst, ook al kan de waarde van de variabele niet worden vervangen. Als het argument bijvoorbeeld een matrixvariabele is, kan er met de procedure geen nieuwe matrix aan worden toegewezen, maar kan het een of meer elementen ervan wijzigen. De gewijzigde elementen worden weergegeven in de onderliggende matrixvariabele in de aanroepende code.
In het volgende voorbeeld worden twee procedures gedefinieerd die een matrixvariabele op waarde nemen en op de elementen ervan werken. Procedure increase voegt er gewoon een toe aan elk element. Procedure replace wijst een nieuwe matrix toe aan de parameter a() en voegt er vervolgens een toe aan elk element. Het opnieuw toewijzen heeft echter geen invloed op de onderliggende matrixvariabele in de aanroepende code, omdat a() deze wordt gedeclareerd ByVal.
Public Sub increase(ByVal a() As Long)
For j As Integer = 0 To UBound(a)
a(j) = a(j) + 1
Next j
End Sub
Public Sub replace(ByVal a() As Long)
Dim k() As Long = {100, 200, 300}
a = k
For j As Integer = 0 To UBound(a)
a(j) = a(j) + 1
Next j
End Sub
In het volgende voorbeeld worden aanroepen uitgevoerd naar increase en replace:
Dim n() As Long = {10, 20, 30, 40}
Call increase(n)
MsgBox("After increase(n): " & CStr(n(0)) & ", " &
CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))
Call replace(n)
MsgBox("After replace(n): " & CStr(n(0)) & ", " &
CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))
In de eerste MsgBox aanroep wordt 'Na toename(n): 11, 21, 31, 41' weergegeven. Omdat n dit een verwijzingstype is, increase kunnen de leden ervan wijzigen, ook al wordt het doorgegeven ByVal.
In de tweede MsgBox aanroep wordt 'Na replace(n): 11, 21, 31, 41' weergegeven. Omdat n deze wordt doorgegeven ByVal, replace kan de variabele n niet worden gewijzigd door er een nieuwe matrix aan toe te wijzen. Wanneer replace u het nieuwe matrixexemplaren k maakt en deze toewijst aan de lokale variabele a, verliest het de verwijzing die n moet worden doorgegeven door de aanroepende code. Wanneer de leden worden averhoogd, wordt alleen de lokale matrix k beïnvloed.
Juiste benadering: Als u een onderliggend variabeleelement zelf wilt wijzigen, geeft u dit door aan de referentie. In het volgende voorbeeld ziet u de wijziging in de declaratie waarin replace de ene matrix kan worden vervangen door een andere in de aanroepende code:
Public Sub replace(ByRef a() As Long)
Kan een overbelasting niet definiëren
Als u een overbelaste versie van een procedure wilt definiëren, moet u dezelfde naam maar een andere handtekening gebruiken. Als de compiler uw declaratie niet kan onderscheiden van een overbelasting met dezelfde handtekening, wordt er een fout gegenereerd.
De handtekening van een procedure wordt bepaald door de naam van de procedure en de parameterlijst. Elke overbelasting moet dezelfde naam hebben als alle andere overbelastingen, maar moet verschillen van allemaal in ten minste één van de andere onderdelen van de handtekening. Zie Procedure overloading voor meer informatie.
De volgende items, ook al hebben ze betrekking op de parameterlijst, zijn geen onderdelen van de handtekening van een procedure:
- Procedureaanpassingstrefwoorden, zoals
Public,SharedenStatic. - Parameternamen.
- Parameteraanpassingstrefwoorden, zoals
ByRefenOptional. - Het gegevenstype van de retourwaarde (met uitzondering van een conversieoperator).
U kunt een procedure niet overbelasten door slechts een of meer van de voorgaande items te variëren.
Juiste benadering: Als u een overbelasting van een procedure wilt definiëren, moet u de handtekening variëren. Omdat u dezelfde naam moet gebruiken, moet u het aantal, de volgorde of de gegevenstypen van de parameters variëren. In een algemene procedure kunt u het aantal typeparameters variëren. In een conversieoperator (CType Operator) kunt u het retourtype variëren.
Overbelastingsresolutie met optionele en ParamArray-argumenten
Als u een procedure overbelast met een of meer optionele parameters of een parameter ParamArray , moet u het dupliceren van impliciete overbelastingen voorkomen. Zie Overwegingen bij overbelastingsprocedures voor meer informatie.
De verkeerde versie van een overbelaste procedure aanroepen
Als een procedure meerdere overbelaste versies heeft, moet u bekend zijn met alle bijbehorende parameterlijsten en begrijpen hoe Visual Basic aanroepen tussen de overbelastingen oplost. Anders kunt u een andere overbelasting aanroepen dan de beoogde.
Wanneer u hebt vastgesteld welke overbelasting u wilt aanroepen, moet u rekening houden met de volgende regels:
- Geef het juiste aantal argumenten en in de juiste volgorde op.
- In het ideale geval moeten uw argumenten exact dezelfde gegevenstypen hebben als de bijbehorende parameters. In elk geval moet het gegevenstype van elk argument worden uitgebreid tot dat van de bijbehorende parameter. Dit geldt zelfs als de optie strikte instructie is ingesteld op
Off. Als voor een overbelasting een beperkte conversie van uw argumentenlijst is vereist, komt deze overbelasting niet in aanmerking om aan te roepen. - Als u argumenten opgeeft waarvoor widening is vereist, maakt u de bijbehorende gegevenstypen zo dicht mogelijk bij de bijbehorende parametergegevenstypen. Als twee of meer overbelastingen uw argumentgegevenstypen accepteren, wordt uw aanroep door de compiler omgezet naar de overbelasting die de minste hoeveelheid widening aanroept.
U kunt de kans verkleinen dat het gegevenstype niet overeenkomt met behulp van het trefwoord CType-functieconversie bij het voorbereiden van uw argumenten.
Fout bij overbelastingsoplossing
Wanneer u een overbelaste procedure aanroept, probeert de compiler alle overbelastingen te elimineren. Als het lukt, wordt de aanroep van die overbelasting opgelost. Als alle overbelastingen worden geëlimineerd of als het de in aanmerking komende overbelastingen niet kan verminderen tot één kandidaat, wordt er een fout gegenereerd.
In het volgende voorbeeld ziet u het oplossingsproces voor overbelasting:
Overloads Sub z(ByVal x As Byte, ByVal y As Double)
End Sub
Overloads Sub z(ByVal x As Short, ByVal y As Single)
End Sub
Overloads Sub z(ByVal x As Integer, ByVal y As Single)
End Sub
Dim r, s As Short
Call z(r, s)
Dim p As Byte, q As Short
' The following statement causes an overload resolution error.
Call z(p, q)
In de eerste aanroep elimineert de compiler de eerste overbelasting omdat het type van het eerste argument (Short) beperkt tot het type van de bijbehorende parameter (Byte). Het elimineert vervolgens de derde overbelasting omdat elk argumenttype in de tweede overbelasting (Short en Single) breder wordt naar het bijbehorende type in de derde overbelasting (Integer en Single). De tweede overbelasting vereist minder verbreeding, dus de compiler gebruikt deze voor de aanroep.
In de tweede aanroep kan de compiler geen overbelastingen elimineren op basis van vermaling. Het elimineert de derde overbelasting om dezelfde reden als in de eerste aanroep, omdat deze de tweede overbelasting kan aanroepen met minder verbreiding van de argumenttypen. De compiler kan echter niet worden opgelost tussen de eerste en tweede overbelasting. Elk heeft één gedefinieerd parametertype dat breder wordt naar het overeenkomstige type in het andere (Byte tot Short, maar Single aan Double). De compiler genereert daarom een overbelastingsoplossingsfout.
Juiste benadering: Als u een overbelaste procedure zonder dubbelzinnigheid wilt aanroepen, gebruikt u de CType-functie om de argumentgegevenstypen aan te passen aan de parametertypen. In het volgende voorbeeld ziet u een aanroep van z die oplossing tot de tweede overbelasting.
Call z(CType(p, Short), CType(q, Single))
Overbelastingsresolutie met optionele en ParamArray-argumenten
Als twee overbelastingen van een procedure identieke handtekeningen hebben, behalve dat de laatste parameter optioneel wordt gedeclareerd in een en ParamArray in de andere, lost de compiler een aanroep naar die procedure op volgens de dichtstbijzijnde overeenkomst. Zie Overbelastingsresolutie voor meer informatie.