Compartir a través de


Procedimientos de solución de problemas (Visual Basic)

En esta página se enumeran algunos problemas comunes que pueden producirse al trabajar con procedimientos.

Devolver un tipo de matriz de un procedimiento de función

Si un Function procedimiento devuelve un tipo de datos de matriz, no puede usar el Function nombre para almacenar valores en los elementos de la matriz. Si intenta hacerlo, el compilador lo interpreta como una llamada a .Function En el ejemplo siguiente se generan errores del compilador:

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

La instrucción AllOnes(i) = 1 genera un error del compilador porque parece llamar AllOnes a con un argumento del tipo de datos incorrecto (un escalar Integer en lugar de una Integer matriz). La instrucción Return AllOnes() genera un error del compilador porque parece llamar AllOnes a sin argumento.

Enfoque correcto: Para poder modificar los elementos de una matriz que se va a devolver, defina una matriz interna como una variable local. En el ejemplo siguiente se compila sin error:

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

Argumento no modificado por llamada a procedimiento

Si piensa permitir que un procedimiento cambie un elemento de programación subyacente a un argumento en el código que realiza la llamada, debe pasarlo por referencia. Pero un procedimiento puede tener acceso a los elementos de un argumento de tipo de referencia incluso si se pasa por valor.

  • Variable subyacente. Para permitir que el procedimiento reemplace el valor del propio elemento de variable subyacente, el procedimiento debe declarar el parámetro ByRef. Además, el código de llamada no debe incluir el argumento entre paréntesis, ya que esto invalidaría el mecanismo de ByRef paso.

  • Elementos de tipo de referencia. Si declara un parámetro ByVal, el procedimiento no puede modificar el propio elemento de variable subyacente. Sin embargo, si el argumento es un tipo de referencia, el procedimiento puede modificar los miembros del objeto al que apunta, aunque no pueda reemplazar el valor de la variable. Por ejemplo, si el argumento es una variable de matriz, el procedimiento no puede asignarle una nueva matriz, pero puede cambiar uno o varios de sus elementos. Los elementos modificados se reflejan en la variable de matriz subyacente en el código de llamada.

En el ejemplo siguiente se definen dos procedimientos que toman una variable de matriz por valor y operan en sus elementos. El procedimiento increase simplemente agrega uno a cada elemento. El procedimiento replace asigna una nueva matriz al parámetro a() y, a continuación, agrega una a cada elemento. Sin embargo, la reasignación no afecta a la variable de matriz subyacente en el código que realiza la llamada porque a() se declara 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

En el ejemplo siguiente se realizan llamadas a increase y replace:

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)))

La primera MsgBox llamada muestra "After increase(n): 11, 21, 31, 41". Dado que n es un tipo de referencia, increase puede cambiar sus miembros, aunque se pase ByVal.

La segunda MsgBox llamada muestra "After replace(n): 11, 21, 31, 41". Dado que n se pasa ByVal, replace no se puede modificar la variable n asignando una nueva matriz a ella. Cuando replace crea la nueva instancia k de matriz y la asigna a la variable alocal , pierde la referencia a n pasada por el código que realiza la llamada. Cuando incrementa los miembros de a, solo se ve afectada la matriz k local.

Enfoque correcto: Para poder modificar un elemento de variable subyacente, páselo por referencia. En el ejemplo siguiente se muestra el cambio en la declaración de replace que permite reemplazar una matriz por otra en el código de llamada:

Public Sub replace(ByRef a() As Long)

No se puede definir una sobrecarga

Si desea definir una versión sobrecargada de un procedimiento, debe usar el mismo nombre pero una firma diferente. Si el compilador no puede diferenciar la declaración de una sobrecarga con la misma firma, genera un error.

La firma de un procedimiento viene determinada por el nombre del procedimiento y la lista de parámetros. Cada sobrecarga debe tener el mismo nombre que todas las demás sobrecargas, pero debe diferir de todas ellas en al menos uno de los demás componentes de la firma. Para obtener más información, vea Sobrecarga de procedimientos.

Los siguientes elementos, aunque pertenecen a la lista de parámetros, no son componentes de la firma de un procedimiento:

  • Palabras clave modificadores de procedimiento, como Public, Sharedy Static.
  • Nombres de parámetro.
  • Palabras clave del modificador de parámetros, como ByRef y Optional.
  • Tipo de datos del valor devuelto (excepto para un operador de conversión).

No se puede sobrecargar un procedimiento variando solo uno o varios de los elementos anteriores.

Enfoque correcto: Para poder definir una sobrecarga de procedimiento, debe variar la firma. Dado que debe usar el mismo nombre, debe variar el número, el pedido o los tipos de datos de los parámetros. En un procedimiento genérico, puede variar el número de parámetros de tipo. En un operador de conversión (operador CType), puede variar el tipo de valor devuelto.

Resolución de sobrecarga con argumentos Optional y ParamArray

Si sobrecarga un procedimiento con uno o varios parámetros Opcionales o un parámetro ParamArray , debe evitar duplicar cualquiera de las sobrecargas implícitas. Para obtener información, vea Consideraciones sobre procedimientos de sobrecarga.

Llamar a la versión incorrecta de un procedimiento sobrecargado

Si un procedimiento tiene varias versiones sobrecargadas, debe estar familiarizado con todas sus listas de parámetros y comprender cómo Visual Basic resuelve las llamadas entre las sobrecargas. De lo contrario, podría llamar a una sobrecarga distinta de la prevista.

Cuando haya determinado qué sobrecarga desea llamar, tenga cuidado de observar las reglas siguientes:

  • Proporcione el número correcto de argumentos y en el orden correcto.
  • Idealmente, los argumentos deben tener exactamente los mismos tipos de datos que los parámetros correspondientes. En cualquier caso, el tipo de datos de cada argumento debe ampliarse al de su parámetro correspondiente. Esto es cierto incluso con la instrucción Option Strict establecida Offen . Si una sobrecarga requiere una conversión de restricción de la lista de argumentos, esa sobrecarga no es apta para llamarse.
  • Si proporciona argumentos que requieren ampliación, haga que sus tipos de datos se acerquen lo más posible a los tipos de datos de parámetro correspondientes. Si dos o más sobrecargas aceptan los tipos de datos de argumento, el compilador resuelve la llamada a la sobrecarga que llama a la menor cantidad de ampliación.

Puede reducir la posibilidad de que los tipos de datos no coincidan mediante la palabra clave de conversión de función CType al preparar los argumentos.

Error de resolución de sobrecarga

Cuando se llama a un procedimiento sobrecargado, el compilador intenta eliminar todas las sobrecargas, excepto una de las sobrecargas. Si se ejecuta correctamente, resuelve la llamada a esa sobrecarga. Si elimina todas las sobrecargas o si no puede reducir las sobrecargas aptas a un solo candidato, genera un error.

En el ejemplo siguiente se muestra el proceso de resolución de sobrecarga:

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)

En la primera llamada, el compilador elimina la primera sobrecarga porque el tipo del primer argumento (Short) se limita al tipo del parámetro correspondiente (Byte). A continuación, elimina la tercera sobrecarga porque cada tipo de argumento de la segunda sobrecarga (Short y Single) amplía al tipo correspondiente en la tercera sobrecarga (Integer y Single). La segunda sobrecarga requiere menos ampliación, por lo que el compilador lo usa para la llamada.

En la segunda llamada, el compilador no puede eliminar ninguna de las sobrecargas en función del restricción. Elimina la tercera sobrecarga por la misma razón que en la primera llamada, ya que puede llamar a la segunda sobrecarga con menos ampliación de los tipos de argumentos. Sin embargo, el compilador no puede resolverse entre las sobrecargas primera y segunda. Cada uno tiene un tipo de parámetro definido que amplía al tipo correspondiente en el otro (Byte a Short, pero Single a Double). Por lo tanto, el compilador genera un error de resolución de sobrecarga.

Enfoque correcto: Para poder llamar a un procedimiento sobrecargado sin ambigüedad, use la función CType para hacer coincidir los tipos de datos de argumento con los tipos de parámetro. En el ejemplo siguiente se muestra una llamada a z que fuerza la resolución a la segunda sobrecarga.

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

Resolución de sobrecarga con argumentos Optional y ParamArray

Si dos sobrecargas de un procedimiento tienen firmas idénticas, excepto que el último parámetro se declara Opcional en uno y ParamArray en el otro, el compilador resuelve una llamada a ese procedimiento según la coincidencia más cercana. Para obtener más información, consulte Resolución de sobrecargas.

Consulte también