Delen via


Procedures voor probleemoplossing (Visual Basic)

Deze pagina bevat 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 dit als een aanroep van 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 te worden aangeroepen AllOnes met een argument van het verkeerde gegevenstype (een scalaire Integer in plaats van een Integer matrix). De instructie Return AllOnes() genereert een compilerfout omdat deze zonder argument lijkt aan te roepen AllOnes .

Juiste aanpak: Als u de elementen wilt wijzigen van een matrix 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 procedureaanroep

Als u een procedure wilt toestaan om een programmeerelement te wijzigen dat ten grondslag is aan een argument in de aanroepende code, moet u deze doorgeven via verwijzing. Maar een procedure heeft toegang tot de elementen van een verwijzingstypeargument, zelfs als u deze waarde doorgeeft.

  • 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 plaatst, omdat dit het ByRef doorgevende 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 de procedure er geen nieuwe matrix aan toewijzen, maar wel een of meer van de bijbehorende elementen 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 eenvoudig één toe aan elk element. Procedure replace wijst een nieuwe matrix toe aan de parameter a() en voegt er vervolgens een toe aan elk element. De hertoewijzing heeft echter geen invloed op de onderliggende matrixvariabele in de aanroepende code, omdat a() is 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)))

Bij de eerste MsgBox aanroep wordt 'Na verhoging(n): 11, 21, 31, 41' weergegeven. Omdat n een verwijzingstype is, increase kunnen de leden ervan wijzigen, zelfs als het wordt doorgegeven ByVal.

Bij de tweede MsgBox aanroep wordt 'Na vervangen(n): 11, 21, 31, 41' weergegeven. Omdat n wordt doorgegeven ByVal, replace kan de variabele n niet worden gewijzigd door er een nieuwe matrix aan toe te wijzen. Wanneer replace het nieuwe matrixexemplaren k wordt gemaakt en deze wordt toegewezen aan de lokale variabele a, verliest het de verwijzing waarnaar n wordt doorgegeven door de aanroepende code. Wanneer de leden van aworden verhoogd, wordt alleen de lokale matrix k beïnvloed.

Juiste aanpak: Als u een onderliggend variabele-element zelf wilt kunnen wijzigen, geeft u het door aan de referentie. In het volgende voorbeeld ziet u de wijziging in de declaratie van replace , waardoor de ene matrix kan worden vervangen door een andere in de aanroepende code:

Public Sub replace(ByRef a() As Long)

Kan geen overbelasting 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 lijst met parameters. Elke overbelasting moet dezelfde naam hebben als alle andere overbelastingen, maar moet in ten minste één van de andere onderdelen van de handtekening afwijken van alle. Zie Procedure overloading (Procedure overloading) voor meer informatie.

De volgende items, hoewel ze betrekking hebben op de lijst met parameters, zijn geen onderdelen van de handtekening van een procedure:

  • Trefwoorden voor procedureaanpassing, zoals Public, Shareden Static.
  • Parameternamen.
  • Parameter modifier trefwoorden, zoals ByRef en Optional.
  • 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 aanpak: 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 Function) kunt u het retourtype variëren.

Overbelastingsoplossing met de argumenten Optioneel en ParamArray

Als u een procedure overbelast met een of meer optionele parameters of een ParamArray-parameter , moet u voorkomen dat een van de impliciete overbelastingen wordt gedupliceerd. Zie Overwegingen in 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 overbelasting.

Wanneer u hebt bepaald welke overbelasting u wilt aanroepen, moet u de volgende regels in acht nemen:

  • 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 breder worden naar dat van de bijbehorende parameter. Dit geldt zelfs als de instructie Option Strict is ingesteld op Off. Als voor een overbelasting een narrowing-conversie van uw argumentenlijst is vereist, komt die overbelasting niet in aanmerking om te worden aangeroepen.
  • Als u argumenten opgeeft waarvoor verbreding nodig is, moet u hun gegevenstypen zo dicht mogelijk bij de bijbehorende parametergegevenstypen opgeven. Als twee of meer overbelastingen uw argumentgegevenstypen accepteren, lost de compiler uw aanroep op naar de overbelasting die de minste verbreding vereist.

U kunt de kans op niet-overeenkomende gegevenstypen verkleinen door het conversiefwoord CType Function te gebruiken bij het voorbereiden van uw argumenten.

Oplossingsfout voor overbelasting

Wanneer u een overbelaste procedure aanroept, probeert de compiler alle overbelastingen op één na te elimineren. Als dit lukt, wordt de aanroep van die overbelasting opgelost. Als alle overbelastingen worden weggenomen of als het de in aanmerking komende overbelastingen niet tot één kandidaat kan verminderen, 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) wordt beperkt tot het type van de bijbehorende parameter (Byte). Vervolgens wordt de derde overbelasting geëlimineerd, 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 verbreding, dus de compiler gebruikt deze voor de aanroep.

In de tweede aanroep kan de compiler geen van de overbelastingen elimineren op basis van vernauwing. Het elimineert de derde overbelasting om dezelfde reden als in de eerste aanroep, omdat het de tweede overbelasting kan aanroepen met minder verbreding van de argumenttypen. De compiler kan echter niet oplossen tussen de eerste en tweede overbelasting. Elk heeft één gedefinieerd parametertype dat wordt breder naar het bijbehorende type in het andere type (Byte naar Short, maar Single naar Double). De compiler genereert daarom een overbelastingsoplossingsfout.

Juiste aanpak: Als u een overbelaste procedure zonder dubbelzinnigheid wilt aanroepen, gebruikt u CType Function om de argumentgegevenstypen te koppelen aan de parametertypen. In het volgende voorbeeld ziet u een aanroep van z die de oplossing tot de tweede overbelasting dwingt.

Call z(CType(p, Short), CType(q, Single))

Overbelastingsoplossing met de argumenten Optioneel en ParamArray

Als twee overbelastingen van een procedure identieke handtekeningen hebben, behalve dat de laatste parameter is gedeclareerd als Optioneel in de ene en ParamArray in de andere, wordt een aanroep van die procedure opgelost volgens de dichtstbijzijnde overeenkomst. Zie Overbelastingsoplossing voor meer informatie.

Zie ook