Procedimientos genéricos en Visual Basic

Un procedimiento genérico, también denominado método genérico, es un procedimiento definido con al menos un parámetro de tipo. Esto permite que el código de llamada adapte los tipos de datos a sus requisitos cada vez que llama al procedimiento.

Un procedimiento no es genérico simplemente en virtud de definirse dentro de una clase genérica o una estructura genérica. Para ser genérico, el procedimiento debe tomar al menos un parámetro de tipo, además de cualquier parámetro normal que pueda tomar. Una clase o estructura genéricas puede contener procedimientos no genéricos y una clase, estructura o módulo no genéricos.

Un procedimiento genérico puede usar sus parámetros de tipo en su lista de parámetros normales, en su tipo de valor devuelto si tiene uno y en su código de procedimiento.

Inferencia de tipos

Puede llamar a un procedimiento genérico sin proporcionar ningún argumento de tipo. Si lo llama de esta manera, el compilador intenta determinar los tipos de datos adecuados para pasar a los argumentos de tipo del procedimiento. Esto se denomina inferencia de tipos. En el código siguiente se muestra una llamada en la que el compilador deduce que debe pasar el tipo String al parámetro de tipo t.

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

Si el compilador no puede deducir los argumentos de tipo del contexto de la llamada, notifica un error. Una posible causa de este error es un error de coincidencia de rango de matriz. Por ejemplo, supongamos que define un parámetro normal como una matriz de un parámetro de tipo. Si llama al procedimiento genérico que proporciona una matriz de una clasificación diferente (número de dimensiones), la falta de coincidencia hace que se produzca un error en la inferencia de tipos. En el código siguiente se muestra una llamada en la que se pasa una matriz bidimensional a un procedimiento que espera una matriz unidimensional.

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

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

Solo puede invocar la inferencia de tipos si se omiten todos los argumentos de tipo. Si proporciona un argumento de tipo, debe proporcionarlos todos.

La inferencia de tipos solo se admite para procedimientos genéricos. No se puede invocar la inferencia de tipos en clases, estructuras, interfaces o delegados genéricos.

Ejemplo

Descripción

En el ejemplo siguiente se define un procedimiento Function genérico para buscar un elemento determinado en una matriz. Define un parámetro de tipo y lo usa para construir los dos parámetros en la lista de parámetros.

Código

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

Comentarios

En el ejemplo anterior se requiere la capacidad de comparar searchValue con cada elemento de searchArray. Para garantizar esta capacidad, restringe el parámetro de tipo T para implementar la interfaz IComparable<T>. El código usa el método CompareTo en lugar del operador =, porque no hay ninguna garantía de que un argumento de tipo proporcionado para que T admita el operador =.

Puede probar el procedimiento findElement con el siguiente código.

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

El anterior llama a MsgBox para mostrar "0", "1" y "-1", respectivamente.

Consulte también