Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ez a lap felsorol néhány gyakori problémát, amelyek az eljárások használatakor fordulhatnak elő.
Tömbtípus visszaadása függvényműveletbő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ó úgy értelmezi, mint a hívás a Function. Az alábbi példa fordítási 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ív.AllOnes 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í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 eljáráshívás által nem módosított argumentum
Ha engedélyezni szeretné, hogy egy eljárás módosítsa a hívó kódban egy argumentum alapjául szolgáló programozási elemet, azt hivatkozással kell átadnia. Egy eljárás azonban akkor is hozzáférhet egy hivatkozástípus-argumentum elemeihez, ha értéket ad át.
Mögöttes változó. Ahhoz, hogy az eljárás helyettesítse a mögöttes változóelem é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ülírná az
ByRefátengedési mechanizmust.Referenciatípus-elemek. Ha byVal paramétert deklarál, az eljárás nem tudja módosítani magát az alapul szolgáló változóelemet. 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 a hívó kód mögöttes tömbváltozójában jelennek meg.
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 egyet 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 újbóli hozzá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 meghívja a következőt increasereplace:
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: "A növekedés után(n): 11, 21, 31, 41". Mivel n hivatkozástípusról van szó, increase akkor is módosíthatja a tagjait, ha át lett adva ByVal.
A második MsgBox hívás a következőt jeleníti meg: "After replace(n): 11, 21, 31, 41". Mivel n az átadás megtörtént ByVal, replace a 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, elveszíti a hívókód által átadott hivatkozást n . Ha növeli a tagok körét a, csak a helyi tömb k lesz érintett.
Helyes megközelítés: Az alapul szolgáló változóelem módosításához adja át azt hivatkozással. Az alábbi példa azt mutatja be, hogy milyen változás történt a deklarációban replace , 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 egy másik aláírást. 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ésnek, 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ésStatic. - Paraméternevek.
- Paraméter módosító kulcsszavak, például
ByRefésOptional. - 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 egy eljárást.
Helyes megközelítés: Az eljárás túlterhelésének meghatározásához meg kell változtatnia az aláírást. Mivel ugyanazt a nevet kell használnia, meg kell változnia a paraméterek számának, sorrendjének vagy adattípusának. Egy általános eljárásban módosíthatja a típusparaméterek számát. A konvertálási operátorokban (CType Operátor) 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ó: A túlterhelési eljárások szempontjai.
Túlterhelt eljárás helytelen verziójának meghívása
Ha egy eljárás több túlterhelt verzióval rendelkezik, ismernie kell az összes paraméterlistát, és ismernie kell, hogy a Visual Basic hogyan oldja fel a túlterhelések közötti hívásokat. Ellenkező esetben a tervezetten kívül más túlterhelést is hívhat.
Ha meghatározta, hogy melyik túlterhelést szeretné meghívni, ügyeljen a következő szabályok betartására:
- Adja meg az argumentumok megfelelő számát és a megfelelő sorrendet.
- Ideális esetben az argumentumoknak pontosan ugyanazokkal az adattípusokkal kell rendelkezniük, mint a megfelelő paraméterek. 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 .
OffHa egy túlterheléshez az argumentumlistából való bármilyen szűkítési átalakítás szükséges, akkor 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éter-adattípusokhoz. Ha két vagy több túlterhelés fogadja el az argumentum adattípusait, a fordító feloldja a hívását arra a túlterhelésre, amely a legkisebb mértékű szélesítést kéri.
Az argumentumok előkészítésekor a CType függvény konvertálási kulcsszóval csökkentheti az adattípus-eltérések esélyét.
Túlterhelésfeloldási hiba
Ha túlterhelt eljárást hív meg, a fordító megpróbálja kiküszöbölni a túlterhelések egyikét. Ha sikerül, feloldja a túlterhelésre irányuló hívást. Ha kiküszöböli az összes túlterhelést, vagy ha 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 (Short) típusa a megfelelő paraméter (Byte) típusára szűkül. Ezután megszünteti a harmadik túlterhelést, mert a második túlterhelés minden argumentumtípusa (Short és Single) a harmadik túlterhelés megfelelő típusára (Integer és Single) szélesedik. A második túlterhelés kisebb szélesítést igényel, ezért a fordító azt 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. A harmadik túlterhelést ugyanazért szünteti meg, mint az első hívásban, mivel a második túlterhelést az argumentumtípusok kevésbé szélesítésével hívhatja meg. A fordító azonban nem tud feloldani az első és a második túlterhelés között. Mindegyiknek van egy definiált paramétertípusa, amely a másikban a megfelelő típusra szélesít (Byte a következőre Short, de Single a következőre Double). A fordító ezért túlterhelés-feloldási hibát okoz.
Helyes megközelítés: Ha egy túlterhelt eljárást kétértelműség nélkül szeretne meghívni, használja a CType függvényt az argumentum adattípusainak a paramétertípusokhoz való egyeztetéséhez. Az alábbi példa egy olyan hívást z mutat be, 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.