Sdílet prostřednictvím


Postupy řešení potíží (Visual Basic)

Na této stránce jsou uvedeny některé běžné problémy, ke kterým může dojít při práci s postupy.

Vrácení typu pole z procedury funkce

Pokud procedura Function vrátí datový typ pole, nelze použít Function název k uložení hodnot v prvech pole. Pokud se to pokusíte provést, kompilátor ho interpretuje jako volání Function. Následující příklad generuje chyby kompilátoru:

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

AllOnes(i) = 1 Příkaz vygeneruje chybu kompilátoru, protože se zdá, že volá AllOnes argument nesprávného datového typu (skalární Integer místo Integer pole). Return AllOnes() Příkaz vygeneruje chybu kompilátoru, protože se zdá, že volá AllOnes bez argumentu.

Správný přístup: Chcete-li být schopni upravit prvky pole, které má být vráceno, definujte interní pole jako místní proměnnou. Následující příklad se zkompiluje bez chyby:

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 není upraven voláním procedury.

Pokud chcete povolit proceduru změnit programovací prvek základní argument ve volajícím kódu, musíte jej předat odkazem. Procedura ale může přistupovat k prvkům argumentu typu odkazu, i když ji předáte hodnotou.

  • Podkladová proměnná. Chcete-li, aby procedura nahradila hodnotu samotného elementu podkladové proměnné, musí procedura deklarovat parametr ByRef. Volající kód také nesmí uzavřít argument do závorek, protože by přepsal ByRef mechanismus předávání.

  • Prvky typu odkazu. Pokud deklarujete parametr ByVal, procedura nemůže upravit samotný element podkladové proměnné. Pokud je však argument referenčním typem, může procedura upravit členy objektu, na který odkazuje, i když nemůže nahradit hodnotu proměnné. Pokud je argument například proměnnou pole, nemůže mu procedura přiřadit novou matici, ale může změnit jeden nebo více jeho prvků. Změněné prvky se projeví v podkladové maticové proměnné ve volajícím kódu.

Následující příklad definuje dva postupy, které přebírají proměnnou pole podle hodnoty a pracují s jeho prvky. Procedura increase jednoduše přidá jeden do každého prvku. Procedura replace přiřadí parametru a() nové pole a poté přidá jedno do každého prvku. Změna přiřazení však nemá vliv na základní proměnnou pole ve volajícím kódu, protože a() je deklarována 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

Následující příklad provádí volání a 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)))

První MsgBox volání zobrazí "Po zvýšení(n): 11, 21, 31, 41". Vzhledem k tomu n , že je typ odkazu, increase může změnit jeho členy, i když je předán ByVal.

Druhé MsgBox volání zobrazí "Po nahrazení(n): 11, 21, 31, 41". Protože n je předán ByVal, replace nelze upravit proměnnou n přiřazením nového pole. Když replace vytvoří novou instanci k pole a přiřadí ji k místní proměnné a, ztratí odkaz n předávaný volajícím kódem. Když zvýší počet členů a, bude ovlivněn pouze místní pole k .

Správný přístup: Chcete-li, aby bylo možné upravit samotný element podkladové proměnné, předejte ho odkazem. Následující příklad ukazuje změnu v deklaraci replace , která umožňuje nahradit jedno pole jiným ve volajícím kódu:

Public Sub replace(ByRef a() As Long)

Nejde definovat přetížení

Pokud chcete definovat přetíženou verzi procedury, musíte použít stejný název, ale jiný podpis. Pokud kompilátor nemůže odlišit deklaraci od přetížení se stejným podpisem, vygeneruje chybu.

Podpis procedury je určen názvem procedury a seznamem parametrů. Každé přetížení musí mít stejný název jako všechna ostatní přetížení, ale musí se lišit od všech v alespoň jedné z ostatních součástí podpisu. Další informace naleznete v tématu Přetížení procedury.

Následující položky, i když se týkají seznamu parametrů, nejsou součástí podpisu procedury:

  • Modifikační klíčová slova procedury, například Public, Shareda Static.
  • Názvy parametrů.
  • Klíčová slova modifikátoru parametrů, například ByRef a Optional.
  • Datový typ návratové hodnoty (s výjimkou operátoru převodu).

Proceduru nelze přetížit tak, že se liší pouze jedním nebo více předchozími položkami.

Správný přístup: Abyste mohli definovat přetížení procedury, musíte podpis lišit. Vzhledem k tomu, že musíte použít stejný název, musíte u parametrů lišit počet, pořadí nebo datové typy. V obecném postupu se může lišit počet parametrů typu. V operátoru převodu (CType – operátor) můžete návratový typ lišit.

Rozlišení přetížení s volitelnými argumenty a argumenty ParamArray

Pokud přetěžujete proceduru s jedním nebo více volitelnými parametry nebo parametrem ParamArray , musíte se vyhnout duplikování jakéhokoli implicitního přetížení. Informace naleznete v tématu Aspekty přetížení procedur.

Volání nesprávné verze přetížené procedury

Pokud má procedura několik přetížených verzí, měli byste být obeznámeni se všemi jejich seznamy parametrů a pochopit, jak Visual Basic řeší volání mezi přetíženími. Jinak byste mohli volat jiné přetížení, než je zamýšlený.

Pokud jste zjistili, které přetížení chcete volat, buďte opatrní, abyste dodržovali následující pravidla:

  • Zadejte správný počet argumentů a ve správném pořadí.
  • V ideálním případě by argumenty měly mít přesně stejné datové typy jako odpovídající parametry. V každém případě musí datový typ každého argumentu rozšířit na odpovídající parametr. To platí i v případě, že příkaz Option Strict nastaven na Off. Pokud přetížení vyžaduje zužující převod ze seznamu argumentů, toto přetížení nemá nárok na zavolání.
  • Pokud zadáte argumenty, které vyžadují rozšíření, jejich datové typy co nejblíže odpovídajícím datovým typům parametrů. Pokud dvě nebo více přetížení přijímají datové typy argumentů, kompilátor přeloží vaše volání na přetížení, které volá nejmenší množství rozšíření.

Při přípravěargumentch

Selhání řešení přetížení

Když zavoláte přetíženou proceduru, kompilátor se pokusí odstranit všechna přetížení kromě jednoho z nich. Pokud bude úspěšné, přeloží volání na toto přetížení. Pokud odstraní všechna přetížení nebo pokud nemůže snížit způsobilé přetížení na jednoho kandidáta, vygeneruje chybu.

Následující příklad znázorňuje proces řešení přetížení:

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)

V prvním volání kompilátor eliminuje první přetížení, protože typ prvního argumentu (Short) se zúží na typ odpovídajícího parametru (Byte). Pak eliminuje třetí přetížení, protože každý typ argumentu ve druhém přetížení (Short a Single) rozšiřuje odpovídající typ třetí přetížení (Integer a Single). Druhé přetížení vyžaduje menší rozšíření, takže ho kompilátor používá pro volání.

Ve druhém volání kompilátor nemůže eliminovat žádné přetížení na základě zúžení. Eliminuje třetí přetížení z stejného důvodu jako v prvním volání, protože může volat druhé přetížení s menším rozšířením typů argumentů. Kompilátor však nemůže přeložit mezi prvním a druhým přetížením. Každý má jeden definovaný typ parametru, který rozšiřuje na odpovídající typ v druhém (Byte na Short, ale Single na Double). Kompilátor proto generuje chybu řešení přetížení.

Správný přístup: Chcete-li volat přetíženou proceduru bez nejednoznačnosti, použijte funkci CType k porovnání datových typů argumentů s typy parametrů. Následující příklad ukazuje volání z , které vynutí rozlišení druhé přetížení.

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

Rozlišení přetížení s volitelnými argumenty a argumenty ParamArray

Pokud dvě přetížení procedury mají identické podpisy s tím rozdílem, že poslední parametr je deklarován v jednom a ParamArray v druhé, kompilátor přeloží volání této procedury podle nejbližší shody. Další informace naleznete v tématu Řešení přetížení.

Viz také