Procedury ogólne w Visual Basic
Procedura ogólna, nazywana również metodą ogólną, jest procedurą zdefiniowaną z co najmniej jednym parametrem typu. Dzięki temu kod wywołujący może dostosować typy danych do swoich wymagań za każdym razem, gdy wywołuje procedurę.
Procedura nie jest ogólna po prostu ze względu na definiowanie wewnątrz klasy ogólnej lub struktury ogólnej. Aby być ogólnym, procedura musi przyjmować co najmniej jeden parametr typu, oprócz wszystkich normalnych parametrów, które może przyjmować. Ogólna klasa lub struktura może zawierać procedury niegeneryczne, a niegeneryczna klasa, struktura lub moduł mogą zawierać procedury ogólne.
Procedura ogólna może używać parametrów typu na liście normalnych parametrów, w zwracanym typie, jeśli ma jeden, i w kodzie procedury.
Wnioskowanie o typie
Można wywołać procedurę ogólną bez podawania żadnych argumentów typu. Jeśli wywołasz to w ten sposób, kompilator próbuje określić odpowiednie typy danych, aby przekazać argumenty typu procedury. Jest to nazywane wnioskowaniem typu. Poniższy kod przedstawia wywołanie, w którym kompilator wywnioskuje, że powinien przekazać typ String
do parametru t
typu .
Public Sub testSub(Of t)(ByVal arg As t)
End Sub
Public Sub callTestSub()
testSub("Use this string")
End Sub
Jeśli kompilator nie może wywnioskować argumentów typu z kontekstu wywołania, zgłasza błąd. Jedną z możliwych przyczyn takiego błędu jest niezgodność klasyfikacji tablicy. Załóżmy na przykład, że definiujesz normalny parametr jako tablicę parametru typu. Jeśli wywołasz procedurę ogólną dostarczającą tablicę innej rangi (liczba wymiarów), niezgodność powoduje niepowodzenie wnioskowania typu. Poniższy kod przedstawia wywołanie, w którym tablica dwuwymiarowa jest przekazywana do procedury, która oczekuje tablicy jednowymiarowej.
Public Sub demoSub(Of t)(ByVal arg() As t)
End Sub
Public Sub callDemoSub()
Dim twoDimensions(,) As Integer
demoSub(twoDimensions)
End Sub
Wnioskowanie typu można wywołać tylko przez pominięcie wszystkich argumentów typu. Jeśli podasz jeden argument typu, musisz podać je wszystkie.
Wnioskowanie typu jest obsługiwane tylko w przypadku procedur ogólnych. Nie można wywołać wnioskowania typu w klasach ogólnych, strukturach, interfejsach lub delegatach.
Przykład
opis
W poniższym przykładzie zdefiniowano procedurę ogólną Function
w celu znalezienia określonego elementu w tablicy. Definiuje jeden parametr typu i używa go do konstruowania dwóch parametrów na liście parametrów.
Kod
Public Function findElement(Of T As IComparable) (
ByVal searchArray As T(), ByVal searchValue As T) As Integer
If searchArray.GetLength(0) > 0 Then
For i As Integer = 0 To searchArray.GetUpperBound(0)
If searchArray(i).CompareTo(searchValue) = 0 Then Return i
Next i
End If
Return -1
End Function
Komentarze
Powyższy przykład wymaga możliwości porównania searchValue
z poszczególnymi elementami elementu searchArray
. Aby zagwarantować tę możliwość, ogranicza parametr T
typu w celu zaimplementowania interfejsu IComparable<T> . Kod używa CompareTo metody zamiast =
operatora, ponieważ nie ma gwarancji, że argument typu podany dla T
operatora obsługuje =
operator.
Możesz przetestować procedurę findElement
przy użyciu następującego kodu.
Public Sub tryFindElement()
Dim stringArray() As String = {"abc", "def", "xyz"}
Dim stringSearch As String = "abc"
Dim integerArray() As Integer = {7, 8, 9}
Dim integerSearch As Integer = 8
Dim dateArray() As Date = {#4/17/1969#, #9/20/1998#, #5/31/2004#}
Dim dateSearch As Date = Microsoft.VisualBasic.DateAndTime.Today
MsgBox(CStr(findElement(Of String)(stringArray, stringSearch)))
MsgBox(CStr(findElement(Of Integer)(integerArray, integerSearch)))
MsgBox(CStr(findElement(Of Date)(dateArray, dateSearch)))
End Sub
Poprzednie wywołania do MsgBox
wyświetlania odpowiednio wartości "0", "1" i "-1".