Megosztás a következőn keresztül:


Hibaelhárítási eljárások (Visual Basic)

Ez a lap néhány gyakori problémát sorol fel, amelyek az eljárások használatakor fordulhatnak elő.

Tömbtípus visszaadása függvényeljárásból

Ha egy Function eljárás tömb adattípust ad vissza, a Function névvel nem tárolhat értékeket a tömb elemeiben. Ha megkísérli ezt megtenni, a fordító a függvény hívásaként értelmezi azt.Function Az alábbi példa fordítóhibákat hoz létre:

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

Az utasítás AllOnes(i) = 1 fordítóhibát generál, mert úgy tűnik, hogy helytelen adattípusú argumentummal (tömb helyett Integer skalárisInteger) hívAllOnes. Az utasítás Return AllOnes() fordítóhibát generál, mert úgy tűnik, hogy argumentum nélkül hív AllOnes .

Helyes megközelítés: Ha módosítani szeretné a visszaadni kívánt tömb elemeit, definiáljon egy belső tömböt helyi változóként. Az alábbi példa hiba nélkül fordítja le a következőt:

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

Az argumentumot nem módosítja az eljáráshívás

Ha engedélyezni szeretné, hogy egy eljárás módosítson egy programozási elemet, amely a hívó kód egyik argumentumát alapulja, azt hivatkozással kell átadnia. Egy eljárás azonban akkor is hozzáférhet a hivatkozástípus argumentum elemeihez, ha érték szerint adja át.

  • Mögöttes változó. Ahhoz, hogy az eljárás lecserélhesse magának a mögöttes változóelemnek az értékét, az eljárásnak deklarálnia kell a ByRef paramétert. Emellett a hívó kódnak nem szabad zárójelbe helyeznie az argumentumot, mert az felülbírálná az átadási ByRef mechanizmust.

  • Referenciatípus-elemek. Ha byVal paramétert deklarál, az eljárás nem tudja magát a mögöttes változóelemet módosítani. Ha azonban az argumentum hivatkozástípus, az eljárás módosíthatja annak az objektumnak a tagjait, amelyekre mutat, annak ellenére, hogy nem tudja lecserélni a változó értékét. Ha például az argumentum tömbváltozó, az eljárás nem tud új tömböt hozzárendelni hozzá, de módosíthatja egy vagy több elemét. A módosított elemek megjelennek a hívókód mögöttes tömbváltozójában.

Az alábbi példa két eljárást határoz meg, amelyek érték szerint vesznek fel egy tömbváltozót, és azok elemein működnek. Az eljárás increase egyszerűen hozzáad egy-egy elemet az egyes elemekhez. Az eljárás replace egy új tömböt rendel a paraméterhez a() , majd hozzáad egyet az egyes elemekhez. Az újrahozzárendelés azonban nem befolyásolja a hívó kód mögöttes tömbváltozóját, mert a() deklarált 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

Az alábbi példa a következő hívásokat kezdeményezi a és replacea feléincrease:

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)))

Az első MsgBox hívás a következőt jeleníti meg: "Növekedés után(n): 11, 21, 31, 41". Mivel n hivatkozástípusról van szó, increase módosíthatja a tagjait, annak ellenére, hogy át lett adva ByVal.

A második MsgBox hívás a következőt jeleníti meg: "Csere(n): 11, 21, 31, 41". Az n átadott ByValreplace változó n nem módosítható egy új tömb hozzárendelésével. Amikor replace létrehozza az új tömbpéldányt k , és hozzárendeli a helyi változóhoz a, a hívó kód által átadott hivatkozás n elveszik. Ha növeli a tagokat a, az csak a helyi tömböt k érinti.

Helyes megközelítés: Ha magát az alapul szolgáló változóelemet szeretné módosítani, adja át hivatkozással. Az alábbi példa a deklaráció replace azon módosítását mutatja be, amely lehetővé teszi, hogy az egyik tömböt lecserélje egy másikra a hívókódban:

Public Sub replace(ByRef a() As Long)

Nem lehet túlterhelést definiálni

Ha egy eljárás túlterhelt verzióját szeretné definiálni, ugyanazt a nevet kell használnia, de más aláírást kell használnia. Ha a fordító nem tudja megkülönböztetni a deklarációt az azonos aláírással rendelkező túlterheléstől, hibát okoz.

Az eljárás aláírását az eljárás neve és a paraméterlista határozza meg. Minden túlterhelésnek ugyanazzal a névvel kell rendelkeznie, mint az összes többi túlterhelés, de legalább az aláírás többi összetevőjében el kell térnie az összestől. További információ: Eljárás túlterhelése.

A következő elemek, bár a paraméterlistára vonatkoznak, nem képezik az eljárás aláírásának összetevőit:

  • Eljárásmódosító kulcsszavak, például Public, Shared, és Static.
  • Paraméternevek.
  • Paramétermódosító kulcsszavak, például ByRef és Optional.
  • A visszatérési érték adattípusa (a konverziós operátor kivételével).

A fenti elemek közül csak egy vagy több módosításával nem lehet túlterhelni az eljárásokat.

Helyes megközelítés: Az eljárás túlterheltségének meghatározásához meg kell változtatnia az aláírást. Mivel ugyanazt a nevet kell használnia, meg kell változtatnia a paraméterek számát, sorrendjét vagy adattípusát. Általános eljárás esetén a típusparaméterek száma változhat. Egy konverziós operátorban (CType függvény) a visszatérési típust módosíthatja.

Túlterhelés feloldása választható és ParamArray argumentumokkal

Ha egy vagy több Választható paraméterrel vagy ParamArray paraméterrel túlterhel egy eljárást, el kell kerülnie az implicit túlterhelések duplikálását. További információ: Szempontok a túlterhelési eljárásokban.

Túlterhelt eljárás helytelen verziójának meghívása

Ha egy eljárás több túlterhelt verzióval is rendelkezik, ismernie kell az összes paraméterlistát, és tisztában kell lennie azzal, hogy a Visual Basic hogyan oldja fel a túlterhelések közötti hívásokat. Ellenkező esetben a kívánttól eltérő túlterhelést is hívhat.

Ha megállapította, hogy melyik túlterhelést szeretné meghívni, ügyeljen az alábbi szabályok betartására:

  • Adja meg a megfelelő számú argumentumot, és a megfelelő sorrendben.
  • Ideális esetben az argumentumoknak pontosan ugyanazokkal az adattípusokkal kell rendelkezniük, mint a megfelelő paramétereknek. Az egyes argumentumok adattípusának minden esetben ki kell szélesítenie a megfelelő paraméter adattípusát. Ez akkor is igaz, ha az Option Strict Utasítás értéke Off. Ha egy túlterheltség az argumentumlistából való leszűkítést igényel, a túlterhelés nem hívható meg.
  • Ha olyan argumentumokat ad meg, amelyek szélesítést igényelnek, az adattípusokat a lehető legközelebb kell hoznia a megfelelő paraméteradattípusokhoz. Ha két vagy több túlterhelés fogadja el az argumentum adattípusait, a fordító feloldja a hívást arra a túlterhelésre, amely a legkisebb mértékű szélesítést kéri.

Az argumentumok előkészítésekor csökkentheti az adattípusok eltérésének esélyét a CType függvény konvertálási kulcsszójának használatával.

Túlterhelésfeloldási hiba

Ha túlterhelt eljárást hív meg, a fordító megpróbálja kiküszöbölni az összes túlterhelést. Ha sikerül, feloldja a túlterhelésre irányuló hívást. Ha kiküszöböli az összes túlterhelést, vagy nem tudja egyetlen jelöltre csökkenteni a jogosult túlterheléseket, hibát okoz.

Az alábbi példa a túlterhelésfeloldási folyamatot szemlélteti:

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)

Az első hívásban a fordító megszünteti az első túlterhelést, mivel az első argumentum típusa (Short) a megfelelő paraméterByte típusára () szűkül. Ezzel kiküszöböli a harmadik túlterhelést, mivel a második túlterhelés (Short és ) argumentumtípusai a harmadik túlterhelés (Integerés SingleSingle) megfelelő típusára szélesednek. A második túlterhelés kisebb szélesítést igényel, ezért a fordító ezt használja a híváshoz.

A második hívásban a fordító nem tudja megszüntetni a túlterheléseket a szűkítés alapján. Kiküszöböli a harmadik túlterhelést ugyanazért, mint az első hívásban, mert meghívhatja a második túlterhelést az argumentumtípusok kevésbé szélesítésével. A fordító azonban nem tud feloldani az első és a második túlterhelés között. Mindegyik egy definiált paramétertípussal rendelkezik, amely a másikban a megfelelő típusra (Bytea értékre, de Single a értékreShort) szélesedik.Double A fordító ezért túlterhelésfeloldási hibát okoz.

Helyes megközelítés: Ha kétértelműség nélkül szeretne meghívni egy túlterhelt eljárást, használja a CType függvényt az argumentum adattípusainak és a paramétertípusoknak való egyeztetéséhez. Az alábbi példában egy hívás z látható, amely a második túlterhelésre kényszeríti a feloldásokat.

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

Túlterhelés feloldása választható és ParamArray argumentumokkal

Ha egy eljárás két túlterhelése azonos aláírással rendelkezik, azzal a kivételével, hogy az utolsó paraméter nem kötelező az egyikben, a másikban a ParamArray , a fordító a legközelebbi egyezésnek megfelelően oldja fel az eljárás hívását. További információ: Túlterhelés feloldás.

Lásd még