Condividi tramite


Generic Procedures in Visual Basic

Una routine generica, detta anche metodo generico, è una routine definita con almeno un parametro di tipo. In questo modo il codice chiamante può adattare i tipi di dati ai relativi requisiti ogni volta che chiama la routine.

Una routine non è generica semplicemente per il fatto di essere definita all'interno di una classe generica o di una struttura generica. Per essere generica, la routine deve accettare almeno un parametro di tipo, oltre a qualsiasi parametro normale che potrebbe accettare. Una classe o una struttura generica può contenere routine non generiche e una classe, una struttura o un modulo non generici possono contenere routine generiche.

Una routine generica può usare i parametri di tipo nell'elenco dei parametri normali, nel tipo restituito, se presente, e nel codice della routine.

Inferenza di tipi

È possibile chiamare una routine generica senza fornire argomenti tipo. Se viene chiamata in questo modo, il compilatore tenta di determinare i tipi di dati appropriati da passare agli argomenti tipo della routine. Questo processo è detto inferenza del tipo. Nel codice seguente viene illustrata una chiamata in cui il compilatore deduce che deve passare il tipo String al parametro di tipo t.

Public Sub testSub(Of t)(ByVal arg As t)
End Sub
Public Sub callTestSub()
    testSub("Use this string")
End Sub

Se il compilatore non riesce a dedurre gli argomenti tipo dal contesto della chiamata, segnala un errore. Una possibile causa di un errore di questo tipo è una mancata corrispondenza della classificazione della matrice. Si supponga, ad esempio, di definire un parametro normale come matrice di un parametro di tipo. Se si chiama la routine generica fornendo una matrice di una classificazione diversa (numero di dimensioni), la mancata corrispondenza causa l'esito negativo dell'inferenza del tipo. Il codice seguente illustra una chiamata in cui viene passata una matrice bidimensionale a una routine che prevede una matrice unidimensionale.

Public Sub demoSub(Of t)(ByVal arg() As t)
End Sub

Public Sub callDemoSub()
    Dim twoDimensions(,) As Integer
    demoSub(twoDimensions)
End Sub

È possibile richiamare l'inferenza del tipo solo omettendo tutti gli argomenti tipo. Se si fornisce un argomento tipo, è necessario fornirli tutti.

L'inferenza del tipo è supportata solo per le routine generiche. Non è possibile richiamare l'inferenza del tipo su classi, strutture, interfacce o delegati generici.

Esempio

Descrizione

Nell'esempio seguente viene definita una routine generica Function per trovare un particolare elemento in una matrice. Viene definito un parametro di tipo che viene usato per costruire i due parametri nell'elenco dei parametri.

Codice

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

Commenti

L'esempio precedente richiede la possibilità di confrontare searchValue con ogni elemento di searchArray. Per garantire questa possibilità, vincola il parametro di tipo T per implementare l'interfaccia IComparable<T>. Il codice usa il metodo CompareTo anziché l'operatore =, perché non esiste alcuna garanzia che un argomento tipo fornito per T supporti l'operatore =.

È possibile testare la routine findElement con il codice seguente.

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

Le chiamate precedenti a MsgBox visualizzano rispettivamente "0", "1" e "-1".

Vedi anche