Generic Procedures in Visual Basic

Una procedura generica, detta anche metodo generico, è una procedura definita con almeno un parametro di tipo. Ciò consente al codice chiamante di personalizzare i tipi di dati ai relativi requisiti ogni volta che chiama la procedura.

Una procedura non è generica semplicemente in base alla definizione all'interno di una classe generica o di una struttura generica. Per essere generico, la procedura deve accettare almeno un parametro di tipo, oltre a tutti i parametri normali che potrebbe richiedere. Una classe o una struttura generica può contenere procedure nongeneriche e una classe, una struttura o un modulo nongenerico può contenere procedure generiche.

Una procedura generica può usare i parametri di tipo nell'elenco dei parametri normali, nel relativo tipo restituito se ne ha uno e nel relativo codice di routine.

Inferenza di tipi

È possibile chiamare una procedura generica senza fornire alcun argomento di tipo. Se lo si chiama in questo modo, il compilatore tenta di determinare i tipi di dati appropriati da passare agli argomenti di tipo della routine. Questo tipo viene chiamato inferenza di tipo. Il codice seguente mostra una chiamata in cui il compilatore inferisce che deve passare il tipo String al parametro tdi tipo .

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

Se il compilatore non può dedurre gli argomenti di 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 procedura generica che fornisce una matrice di un rango diverso (numero di dimensioni), la mancata corrispondenza causa l'esito negativo dell'inferenza del tipo. Il codice seguente mostra una chiamata in cui una matrice bidimensionale viene passata 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 dei tipi solo omettendo tutti gli argomenti di tipo. Se si specifica un argomento di tipo, è necessario specificarli tutti.

L'inferenza dei tipi è supportata solo per le procedure generiche. Non è possibile richiamare l'inferenza dei tipi in classi generiche, strutture, interfacce o delegati.

Esempio

Descrizione

Nell'esempio seguente viene definita una procedura generica Function per trovare un particolare elemento in una matrice. Definisce un parametro di tipo e lo usa 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 capacità, limita il parametro T di tipo per implementare l'interfaccia IComparable<T> . Il codice usa il CompareTo metodo anziché l'operatore = , perché non esiste alcuna garanzia che un argomento di tipo fornito per T supporta l'operatore = .

È possibile testare la findElement procedura 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 per MsgBox visualizzare rispettivamente "0", "1" e "-1".

Vedi anche