Buscador

Sobrecarga de procedimientos - IV

En el ejemplo anterior, cuando llamemos al procedimiento Datos( ), el entorno de .NET Framework, en función de si pasamos o no parámetros al procedimiento, y de cómo sean estos parámetros, ejecutará la versión adecuada del procedimiento. Ya que el protocolo o firma del procedimiento es el elemento que emplea .NET Framework para diferenciar cada una de sus versiones o implementaciones, las listas de parámetros de cada versión deben ser diferentes al menos en uno de los siguientes aspectos: 
• Número de parámetros. 
• Orden de los parámetros. 
• Tipo de dato de los parámetros. Por consiguiente, no es posible crear dos procedimientos sobrecargados que sólo se diferencien en los nombres de los parámetros, por los modificadores de ámbito (Public, Private, etc.), o por el tipo de dato de retorno en el caso de un procedimiento Function.
Una vez vistas las normas y restricciones aplicables a los procedimientos sobrecargados, veamos en el Código fuente 113 como solucionaríamos el problema planteado al comienzo de este apartado empleando esta técnica.


Sub Main()
Dim Dias As Integer
' mostrar datos del empleado según nombre
VerEmpleado("Pedro")
' mostrar datos del empleado según edad
Dias = VerEmpleado(28)
Console.WriteLine("Días libres del empleado: {0}", Dias)
Console.WriteLine()
' mostrar salario pasando las horas trabajadas
VerEmpleado(25, 80)
Console.ReadLine()
End Sub
Overloads Sub VerEmpleado(ByVal Nombre As String)
Console.WriteLine("Datos empleado por nombre")
Console.WriteLine("Nombre del empleado: {0}", Nombre)
Console.WriteLine("Domicilio: Colina Alta,12")
Console.WriteLine("Localidad: Salamanca")
Console.WriteLine()
End Sub
Overloads Function VerEmpleado(ByVal Edad As Integer) As Integer
Dim DiasLibres As Integer
Console.WriteLine("Datos empleado por edad")
Console.WriteLine("Edad del empleado: {0}", Edad)
Console.WriteLine("DNI:21555666")
Console.WriteLine("Fecha de alta en la empresa: 10/4/1997")
Console.WriteLine()
DiasLibres = 5
Return DiasLibres
End Function
Overloads Sub VerEmpleado(ByVal PrecioHora As Integer, ByVal HorasTrabajadas As
Long)
Dim Salario As Long
Salario = PrecioHora * HorasTrabajadas
Console.WriteLine("Salario según horas: {0}", Salario)
Console.WriteLine()
End Sub
Código fuente 113

Sobrecarga de procedimientos - III

Sin embargo, esta solución nos obliga a tener que saber varios nombres de procedimiento, con lo que tampoco ayuda mucho a simplificar el código. ¿No sería ideal, disponer de un único nombre de procedimiento y que este fuera lo suficientemente inteligente para mostrar los datos adecuados en cada caso?, pues esta característica está implementada en VB.NET a través de la sobrecarga de procedimientos. La sobrecarga de procedimientos es una técnica que consiste en crear varias versiones de un mismo procedimiento, distinguiéndose entre sí por la lista de parámetros o protocolo de llamada del procedimiento. Para definir un procedimiento como sobrecargado, debemos comenzar su declaración con la palabra clave Overloads. Podemos utilizar procedimientos tanto Sub como Function cuando realizamos sobrecarga., siendo posible que una de las implementaciones no tenga lista de parámetros. El Código fuente 112 muestra un ejemplo de sobrecarga.

Overloads Sub Datos()
' código del procedimiento
' ............
' ............
End Sub
Overloads Sub Datos(ListaParametrosA)
' código del procedimiento
' ............
' ............
End Sub
Overloads Function Datos(ListaParametrosB) As TipoDatoRetorno
' código del procedimiento
' ............
' ............
End Function
Código fuente 112

Sobrecarga de procedimientos - II

El uso de parámetros opcionales, como acabamos de constatar, resulta engorroso, ya que nos obliga a comprobar qué valor ha sido pasado y mostrar los datos correspondientes en consecuencia. Tenemos además, un inconveniente añadido, y es que podemos pasar los dos parámetros a la vez, con lo que se mostrarían todos los datos, cuando lo que queremos es visualizar un grupo u otro en cada llamada. Una aproximación diferente al problema sería escribir dos procedimientos distintos, y llamar a uno u otro según los datos que necesitemos. Ver Código fuente 111.


Sub Main()
' mostrar datos del empleado según nombre
VerEmpleNombre("Pedro")
' mostrar datos del empleado según edad
VerEmpleNum(28)
Console.ReadLine()
End Sub
Public Sub VerEmpleNombre(ByVal Nombre As String)
Console.WriteLine("Datos empleado por nombre")
Console.WriteLine("Nombre del empleado: {0}", Nombre)
Console.WriteLine("Domicilio: Colina Alta,12")
Console.WriteLine("Localidad: Salamanca")
Console.WriteLine()
End Sub
Public Sub VerEmpleNum(ByVal Edad As Integer)
Console.WriteLine("Datos empleado por edad")
Console.WriteLine("Edad del empleado: {0}", Edad)
Console.WriteLine("DNI:21555666")
Console.WriteLine("Fecha de alta en la empresa: 10/4/1997")
Console.WriteLine()
End Sub
Código fuente 111

Sobrecarga de procedimientos - I

Si bien el uso de parámetros opcionales es un medio para ahorrar al programador el paso de los mismos en situaciones en las que no son necesarios, resulta una solución un tanto artificiosa, ya que lo que realmente hace es complicar más que facilitar la escritura de código. VB.NET aporta al lenguaje una nueva técnica que permite obviar el uso de parámetros opcionales por una solución más elegante y flexible: los procedimientos sobrecargados. Antes de explicar en qué consiste un procedimiento sobrecargado, situémonos en el siguiente escenario: Necesitamos mostrar los datos de un empleado de dos formas, en función del modo de consulta. Por un lado visualizaríamos su nombre, domicilio y localidad; y por otra parte su edad, DNI y fecha de alta en la empresa. Con lo que sabemos hasta el momento, podríamos resolver este problema escribiendo un procedimiento con parámetros opcionales, y según pasáramos un valor u otro, mostrar la información correspondiente. El Código fuente 110 muestra este modo de resolver el problema. El uso de la estructura If...End If será explicado posteriormente en el apartado dedicado a estructuras de control, por lo que aclararemos brevemente al lector que el uso de esta estructura nos permite ejecutar bloques de código en función de que la expresión utilizada a continuación de If se evalúe o no a Verdadero.

Sub Main()
' mostrar datos del empleado
' en función del nombre
VerDatosEmpleado("Pedro")

' mostrar datos del empleado
' en función de la edad
VerDatosEmpleado(, 28)
Console.ReadLine()
End Sub
Sub VerDatosEmpleado(Optional ByVal Nombre As String = "X", Optional ByVal Edad As
Integer = 999)
If Nombre <> "X" Then
Console.WriteLine("Nombre del empleado: {0}", Nombre)
Console.WriteLine("Domicilio: Colina Alta,12")
Console.WriteLine("Localidad: Salamanca")
End If
If Edad <> 999 Then
Console.WriteLine("Edad del empleado: {0}", Edad)
Console.WriteLine("DNI:21555666")
Console.WriteLine("Fecha de alta en la empresa: 10/4/1997")
End If
Console.WriteLine()
End Sub
Código fuente 110

Array de parámetros

Cuando en la lista de parámetros de un procedimiento utilizamos la palabra clave ParamArray junto al nombre del último parámetro de la lista, dicho parámetro será considerado un array, por lo que al hacer la llamada al procedimiento podremos pasarle un número variable de valores, que manejaremos a través del array. El Código fuente 109 muestra un ejemplo.

Sub Main()
Dim Valor As Integer
Dim Ciudad As String
Dim Nombre As String
Valor = 7954
Ciudad = "Valencia"
Nombre = "Jorge"
' en la llamada al procedimiento Prueba()
' todos los valores que pasemos a continuación
' del primer parámetro, serán depositados
' en el array de parámetros
Prueba(Valor, Ciudad, "mesa", Nombre)
Console.ReadLine()
End Sub

' el parámetro MasDatos del procedimiento es un array
' de parámetros variables
Sub Prueba(ByVal Importe As Integer, ByVal ParamArray MasDatos() As String)
Dim Contador As Integer
' mostrar el primer parámetro
Console.WriteLine("Parámetro Importe: {0}", Importe)
Console.WriteLine()
' el resto de parámetros del procedimiento
' están en el array, los obtenemos recorriendolo
' con(una) estructura For...Next
Console.WriteLine("Contenido del array de parámetros MasDatos():")
For Contador = 0 To UBound(MasDatos)
Console.WriteLine("Elemento: {0} - Valor: {1}", _
Contador, MasDatos(Contador))
Next
End Sub
Código fuente 109

Parámetros opcionales

Un parámetro opcional es aquel que no es necesario especificar al hacer la llamada a un procedimiento. Para indicar en la declaración de un procedimiento que un parámetro es opcional, debemos utilizar la palabra clave Optional seguida de la especificación del parámetro, y finalizar con la asignación de un valor por defecto para el parámetro. Teniendo en cuenta además, que a partir del primer parámetro opcional en la lista de un procedimiento, todos los parámetros sucesivos también deben ser opcionales. En el Código fuente 108 creamos una función en la que declaramos un parámetro opcional. Después hacemos dos llamadas a dicho procedimiento, pasando y omitiendo el parámetro opcional respectivamente en cada llamada.

Sub Main()
Dim Localidad As String
Dim Importe As Integer
Dim Resultado As Integer
' ---------------------
Localidad = "Sevilla"
Importe = 15044
' paso de todos los parámetros al procedimiento
Resultado = Calcular(Localidad, Importe)
Console.WriteLine("Primera llamada, valor devuelto: {0}", Resultado)
' ---------------------
Localidad = "Madrid"
' paso sólo del primer parámetro al procedimiento,
' esto hará que se utilice el valor por defecto
' del parámetro opcional
Resultado = Calcular(Localidad)
Console.WriteLine("Segunda llamada, valor devuelto: {0}", Resultado)
Console.ReadLine()
End Sub
Function Calcular(ByVal Ciudad As String, Optional ByVal Cantidad As Integer =
5500) As Integer
Console.WriteLine("Valores de los parámetros")
Console.WriteLine("Ciudad: {0} - Cantidad: {1}", Ciudad, Cantidad)
Return Cantidad + 100
End Function
Código fuente 108

Paso de parámetros por posición y por nombre - II

Podemos mezclar ambos tipos de paso en la llamada a un procedimiento, teniendo en cuenta que los parámetros en los que no utilicemos paso por nombre, deberemos situarlos en su posición correcta. El Código fuente 107 muestra un ejemplo con una variación sobre el ejemplo anterior.


Prueba(Localidad, Fecha:=DiaHoy, Cantidad:=Importe)
Código fuente 107

Paso de parámetros por posición y por nombre - I

Cuando al llamar a un procedimiento con parámetros, pasamos estos en el mismo orden en el que están especificados en la declaración del procedimiento, se dice que se ha realizado un paso de parámetros por posición. Existe además, otro modo de paso de parámetros en el cuál no estamos obligados a situarlos en el mismo orden que indica la declaración, es el llamado paso de parámetros por nombre. En este tipo de paso, debemos situar en la llamada al procedimiento el nombre del parámetro, seguido de los signos de dos puntos e igual ( := ) y finalmente el valor a pasar. El Código fuente 106 muestra unos ejemplos con ambos tipos de paso de parámetros.

Sub Main()
Dim Localidad As String
Dim Importe As Integer
Dim DiaHoy As Date
' ---------------------
Localidad = "Sevilla"
Importe = 15044
DiaHoy = #2/10/2002#
' paso de parámetros por posición
Prueba(Localidad, Importe, DiaHoy)
' ---------------------
Localidad = "Madrid"
Importe = 250
DiaHoy = #5/8/2002#
' paso de parámetros por nombre
Prueba(Cantidad:=Importe, Fecha:=DiaHoy, Ciudad:=Localidad)
Console.ReadLine()
End Sub
Sub Prueba(ByVal Ciudad As String, ByVal Cantidad As Integer, ByVal Fecha As Date)
Console.WriteLine("Valores de los parámetros")
Console.WriteLine("Ciudad: {0} - Cantidad: {1} - Fecha: {2}", Ciudad, Cantidad,
Fecha)
End Sub
Código fuente 106

Paso por referencia (ByRef) - II

Lo que ocurre en el fuente anterior a nivel de gestión interna en memoria de los parámetros es lo siguiente: cuando se realiza la llamada al procedimiento y se pasa el parámetro, el entorno detecta que se trata de un parámetro pasado por referencia, y tanto la variable del código llamador como la del procedimiento llamado utilizan la misma dirección de memoria o referencia hacia los datos, por lo que los cambios realizados en un procedimiento afectarán también al otro. La Figura 68 muestra una representación gráfica de este proceso.


Figura 68. Esquema de gestión interna de variables en el paso por referencia.

Paso por referencia (ByRef) - I

Cuando pasamos un parámetro por referencia a un procedimiento, si modificamos dentro del procedimiento la variable que contiene el parámetro, dichos cambios en este caso sí afectarán al código llamador. Debemos situar en este caso en el procedimiento, la palabra clave ByRef antes del nombre del parámetro. Cambiemos el código del anterior ejemplo, haciendo que en este caso, el parámetro sea pasado por referencia y observemos los resultados. Ver el Código fuente 105.

Sub Main()
Dim Nombre As String
Nombre = "Juan"
Console.WriteLine("Valor de la variable antes de llamar a Prueba(): {0}",
Nombre)
' llamamos a un procedimiento
' y le pasamos una variable por referencia
Prueba(Nombre)
' el cambio realizado al parámetro en el procedimiento
' ha afectado a la variable Nombre, que aquí contiene
' el mismo valor que se asignó en el procedimiento
Console.WriteLine("Valor de la variable al volver a Main(): {0}", Nombre)
Console.ReadLine()
End Sub

Sub Prueba(ByRef ValorMostrar As String)
' modificamos el valor del parámetro
ValorMostrar = "Elena"
Console.WriteLine("Valor del parámetro dentro de Prueba(): {0}", ValorMostrar)
End Sub
Código fuente 105

Paso por valor (ByVal) - II

Lo que ocurre en el fuente anterior a nivel de gestión interna en memoria de los parámetros es lo siguiente: cuando se realiza la llamada al procedimiento y se pasa el parámetro, el entorno detecta que se trata de un parámetro pasado por valor, por lo que crea una nueva variable en memoria que será la que manipulemos dentro del procedimiento. La Figura 67 muestra una representación gráfica de este proceso.
Figura 67. Esquema de gestión interna de variables en el paso por valor.
En el entorno de .NET Framework, por defecto, todos los parámetros son pasados por valor. Esto lo puede comprobar el lector de un modo muy simple: si al declarar un parámetro no especifica el tipo de paso, el IDE automáticamente situará junto a ese parámetro la palabra clave ByVal. Se recomienda siempre que sea posible el paso de parámetros por valor, ya que ayuda a generar un código más optimizado y contribuye a mejorar la encapsulación.

Paso por valor (ByVal) - I

Cuando pasamos un parámetro por valor a un procedimiento, la variable que contiene el parámetro puede ser modificada dentro del procedimiento, sin que estos cambios afecten al valor original en el código llamador. Debemos situar en este caso en el procedimiento, la palabra clave ByVal antes del nombre del parámetro. Ver Código fuente 104.

Sub Main()
Dim Nombre As String
Nombre = "Juan"
' llamamos a un procedimiento
' y le pasamos una variable por valor
Prueba(Nombre)
' la variable que hemos pasado al procedimiento,
' al volver aquí no ha sido cambiada, debido a que
' ha sido pasada por valor, sigue conteniendo
' la cadena "Juan"
Console.WriteLine("Valor de la variable dentro de Main(): {0}", Nombre)
Console.ReadLine()
End Sub
Sub Prueba(ByVal ValorMostrar As String)
' modificamos el valor del parámetro,
' este cambio no afecta a la variable Nombre
ValorMostrar = "Elena"
Console.WriteLine("Valor del parámetro dentro de Prueba(): {0}", ValorMostrar)
End Sub
Código fuente 104

Modos de paso de parámetros a un procedimiento

Existen dos modos en el lenguaje de pasar parámetros a un procedimiento: por valor y por referencia. Este aspecto del lenguaje está relacionado con la forma en que el contenido de los parámetros es gestionado internamente en memoria. Ello nos permitirá según el tipo de paso empleado, poder alterar el valor del parámetro en el código que realizó la llamada.

Tipo de dato de un parámetro

Al igual que hacemos cuando declaramos una variable, al declarar un parámetro debemos especificar el tipo de dato que el parámetro va a contener. Esto será o no obligatorio, en función del modificador establecido en la instrucción Option Strict. En el Código fuente 103 hemos añadido un parámetro de tipo String al procedimiento Prueba( ). Cuando llamemos desde otro procedimiento a Prueba( ), al pasar desde el código llamador una cadena de caracteres, bien de forma literal o en una variable; el contenido de dicha cadena se traspasará a la variable situada en la lista de parámetros del procedimiento, que posteriormente visualizaremos en la consola.

Sub Main()
Dim Nombre As String
Nombre = "Juan"
Prueba(Nombre)
Prueba("Esto es una prueba")

Console.ReadLine()
End Sub
Sub Prueba(ByVal ValorMostrar As String)
Console.WriteLine("El valor del parámetro pasado es {0}", ValorMostrar)
End Sub
Código fuente 103

Protocolo de llamada o firma de un procedimiento

A la lista de parámetros de un procedimiento se le denomina protocolo de llamada o firma (signature) del procedimiento. Se trata de un concepto que cubriremos posteriormente en el apartado dedicado a la sobrecarga de procedimientos.

Paso de parámetros a procedimientos

Un parámetro consiste en un valor que es pasado a un procedimiento. Dicho valor puede ser una variable, constante o expresión. Los procedimientos pueden recibir parámetros en forma de lista de variables separada por comas, siguiendo la sintaxis que vemos en el Código fuente 102.

[Optional] [ByVal | ByRef] [ParamArray] NombreParametro As TipoDato
Código fuente 102

Las reglas y cuestiones sobre paso de parámetros descritas en los siguientes apartados son válidas tanto para procedimientos como para funciones, excepto en aquellos lugares donde se indique lo contrario.

Llamada a un procedimiento Function

Para realizar una llamada o ejecutar un procedimiento Function debemos escribir su nombre en un punto del programa al igual que hacemos con los procedimientos Sub; en este aspecto ambos tipos de procedimiento son iguales. Por otro lado, los puntos que marcan las diferencias entre un Function y un Sub son los siguientes: 
• Un procedimiento Function devuelve un valor, de modo que si queremos obtenerlo, debemos asignar la llamada a la función a una variable. Los procedimientos Sub no pueden devolver valores. 
Debido precisamente a la capacidad de un procedimiento Function de devolver un valor, podemos situar la llamada a una función dentro de una expresión, y operar con el valor de retorno dentro de la expresión, lo cual dota a nuestro código de una mayor flexibilidad. Los procedimientos Sub no pueden formar parte de expresiones. En el Código fuente 101 vemos varios ejemplos de llamadas a la función Calcular( ), según el modo en que vamos a manipular su valor de retorno.


Module Module1
Sub Main()
Dim Resultado As Integer
Dim NuevoValor As Integer
' llamada a una función sin recoger el valor de retorno,
' por este motivo, dicho valor se pierde
Calcular()
' llamada a una función obteniendo el valor
' de retorno y asignando el valor a una variable
Resultado = Calcular()
Console.WriteLine("La variable Resultado contiene: {0}", Resultado)
' llamada a una función como parte de una expresión
NuevoValor = 1500 + Calcular() * 2
Console.WriteLine("La variable NuevoValor contiene: {0}", NuevoValor)
Console.ReadLine()
End Sub
Function Calcular() As Integer
Dim MiValor As Integer
Console.WriteLine("Introducir un número de 1 a 100")
MiValor = Console.ReadLine()
Return MiValor

' también podemos utilizar esta
' sintaxis para devolver el valor
' de retorno de la función:
'Calcular = MiValor
End Function
End Module
Código fuente 101

Sintaxis de un procedimiento Function - II

El Código fuente 100 muestra un sencillo ejemplo de procedimiento Function, en el cual se pide al usuario que introduzca un número que es devuelto como resultado de la función.


Function Calcular() As Integer
Dim MiValor As Integer
Console.WriteLine("Introducir un número de 1 a 100")
MiValor = Console.ReadLine()
Return MiValor
' también podemos utilizar esta
' sintaxis para devolver el valor
' de retorno de la función:
'Calcular = MiValor
End Function
Código fuente 100

En el caso de devolver el valor de retorno de una función utilizando el propio nombre de la función, nos encontramos con el problema de que si en un momento determinado tenemos que cambiar el nombre de la función, también deberemos cambiar todos aquellos puntos de la rutina en donde devolvemos el valor. Por este motivo es recomendable el uso de Return para el devolver el valor de la función, ya que si tenemos que cambiar el nombre de la función, no será necesario modificar los puntos en los que se devuelve el valor de este tipo de procedimiento

Sintaxis de un procedimiento Function - I

El formato para la escritura de un procedimiento Function se muestra en el Código fuente 99.

[Ámbito] Function NombreFunción[(ListaParámetros)] As TipoDato
[CódigoEjecutable]
[Return Valor]
[NombreFunción = Valor]
[Exit Function]
[CódigoEjecutable]
End Function
Código fuente 99
Los elementos que forman parte de este tipo de rutina son los siguientes: 
• Ámbito. Define el modo en que vamos a poder acceder o llamar al procedimiento desde otro punto de la aplicación. El ámbito de los elementos del lenguaje será tratado en un apartado posterior. 
• Function...End Function. Palabras clave que indican el comienzo y final de la función respectivamente. Cuando hagamos una llamada a la función, el compilador ejecutará el código comprendido entre estas dos palabras clave. 
• NombreFunción. Identificador que utilizamos para reconocer y llamar a la función. En este tipo de procedimiento, también utilizamos su nombre para asignar el valor que será devuelto al código llamador en el modo NombreFunción = Valor, en esta última situación, podemos situar esta expresión de devolución en tantos lugares como necesitemos dentro de la función. 
• TipoDato. Tipo de dato del valor devuelto como resultado de la ejecución de la función. 
• ListaParámetros. Lista de identificadores separados por comas, y encerrados entre paréntesis, que representan la información que recibe la función desde el código llamador. Dentro del cuerpo del procedimiento, estos identificadores o parámetros se utilizarán igual que variables. 
• Return. Esta palabra clave permite salir de la ejecución de la función devolviendo al mismo tiempo un valor al código que hizo la llamada. Podemos utilizarla dentro de una función, en tantos lugares como necesitemos.
• Exit Function. Esta palabra clave permite salir de la ejecución de la función sin haber llegado a su fin. Podemos utilizarla dentro de una función, en tantos lugares como necesitemos.

Llamada a un procedimiento Sub

Para realizar una llamada o ejecutar un procedimiento Sub, debemos escribir su nombre en un punto del programa. El Código fuente 98 muestra el código al completo del módulo de nuestra aplicación de consola. La ejecución de este programa comienza como es habitual por Main( ), dentro del cual se realiza una llamada al procedimiento Prueba( ).

Module Module1
Sub Main()
Console.WriteLine("Estamos en el procedimiento Main")
' llamada a un procedimiento
Prueba()
Console.ReadLine()
End Sub
Sub Prueba()
Console.WriteLine("Estamos en el procedimiento Prueba")
End Sub
End Module
Código fuente 98
En la llamada a un procedimiento Sub, el uso de los paréntesis es opcional, independientemente de si pasamos o no parámetros. No obstante, es muy recomendable especificar dichos paréntesis, ya que aportan una gran claridad a nuestro código, de forma que al leerlo podemos ver rápidamente los puntos en los que se realiza una llamada a una rutina de código. Debido a esto, el IDE sitúa automáticamente los paréntesis en el caso de que no los especifiquemos de forma explícita. No es posible situar la llamada a un procedimiento Sub como parte de una expresión, puesto que este tipo de procedimientos, al no devolver un valor, provocaría un error de compilación. Ver Figura 66.
Figura 66. No es posible hacer una llamada a un procedimiento Sub en una expresión.

Sintaxis de un procedimiento Sub

El formato para la escritura de un procedimiento Sub se muestra en el Código fuente 96.

[Ámbito] Sub NombreProcedimiento[(ListaParámetros)]
[CódigoEjecutable]
[Exit Sub | Return]
[CódigoEjecutable]
End Sub
Código fuente 96

Los elementos que forman parte de este tipo de rutina son los siguientes: 
• Ámbito. Define el modo en que vamos a poder acceder o llamar al procedimiento desde otro punto de la aplicación. El ámbito de los elementos del lenguaje será tratado en un apartado posterior. 
• Sub...End Sub. Palabras clave que indican el comienzo y final del procedimiento respectivamente. Cuando hagamos una llamada al procedimiento, el compilador ejecutará el código comprendido entre estas dos palabras clave. 
• NombreProcedimiento. Identificador que utilizamos para reconocer y llamar al procedimiento. 
• ListaParámetros. Lista de identificadores separados por comas, y encerrados entre paréntesis, que representan la información que recibe el procedimiento desde el código llamador. Dentro del cuerpo del procedimiento, estos identificadores o parámetros se utilizarán igual que variables.
• Return. Esta palabra clave permite salir de la ejecución del procedimiento sin haber llegado a su fin. Podemos utilizarla en tantos lugares dentro de un procedimiento como sea necesario. Se recomienda su uso en lugar de Exit Sub, ya que podemos emplear Return para salir de cualquier tipo de procedimiento, con lo cual se unifica la escritura del código. 
• Exit Sub. Al igual que en el punto anterior, esta palabra clave permite salir de la ejecución del procedimiento sin haber llegado a su fin, pudiendo igualmente, situarla en tantos lugares dentro del procedimiento como sea necesario.
El Código fuente 97 muestra el modo más simple de crear un procedimiento. Escriba el lector este procedimiento en la aplicación de consola sobre la que está realizando las pruebas, a continuación de Main( ).

Sub Prueba()
Console.WriteLine("Estamos en el procedimiento Prueba")
End Sub
Código fuente 97

Procedimientos

Todo el código ejecutable de una aplicación se ubica en rutinas de código o procedimientos. Un procedimiento es un elemento del lenguaje compuesto por un conjunto de líneas de código, a las que se denomina cuerpo del procedimiento. 
Su comienzo y fin lo establecemos mediante ciertas palabras reservadas del lenguaje, asociándole un identificador, que nos servirá para reconocerlo entre el resto de procedimientos creados en el programa. Podemos enviarle también información adicional en forma de parámetros, con lo que el resultado de la ejecución de un procedimiento variará según los valores que pasemos en cada llamada. En VB.NET disponemos de los siguientes tipos de procedimientos: 
• Sub. Procedimiento que realiza un conjunto de operaciones pero no devuelve valor al punto de llamada. A lo largo del texto también nos referiremos a las rutinas de tipo Sub con el nombre genérico de procedimiento. 
• Function. Procedimiento que realiza un conjunto de operaciones, y devuelve un valor denominado valor de retorno al punto de código que realizó la llamada. A lo largo del texto también nos referiremos a las rutinas de tipo Function con el nombre genérico de función. 
• Property. Procedimiento que se utiliza para labores de acceso y asignación de valores a las propiedades de un objeto. Serán tratados con más profundidad en los temas dedicados a la programación orientada a objetos.

Escritura de varias sentencias en la misma línea

Aquí tenemos el caso opuesto al anterior apartado. El lenguaje nos permite escribir en una misma línea física, varias sentencias separadas por el carácter de dos puntos ( : ), que en condiciones normales se escriben en líneas separadas. Ver Código fuente 95.

Sub Main()
Dim Valor As Integer, Nombre As String, Resultado As Boolean
' en la siguiente línea hay tres sentencias que
' habitualmente se escriben en líneas separadas
Valor = 50 : Nombre = "Julio" : Resultado = 50 <> 275
Console.WriteLine("Contenido de variables: {0} - {1} - {2}", _
Valor, Nombre, Resultado)
Console.ReadLine()
End Sub
Código fuente 95


Si bien en algunas situaciones puede ser útil, esta característica hace que nuestro código sea más complicado de leer, restándole claridad a nuestra aplicación, por lo que recomendamos no utilizarla salvo en casos muy necesarios.

Procedimientos

División de una línea de código 

Si tenemos en nuestro programa líneas de código muy largas, que nos obliguen a desplazarnos hacia una lateral de la ventana del editor de código para poder leerlas, podemos dividir ese tipo de línea lógica de código en varias líneas físicas, situando el carácter de guión bajo ( _ ) en el punto de la línea de código en donde queremos continuar, teniendo en cuenta que siempre debe haber un espacio en blanco antes y después de este carácter, para que la división de la línea sea efectiva. En el Código fuente 94 podemos ver dos líneas exactamente iguales, la primera se muestra en una sola línea física, mientras que la segunda ha sido fraccionada en tres líneas, aunque a efectos de compilación el resultado es el mismo.

Dim Resultado As Boolean
' una sola línea lógica y física
Resultado = ((30 + 5) * 5 > 100) And (52 > 200 / (2 + 5))
' varias líneas físicas, aunque internamente
' el compilador reconoce una sola línea lógica
Resultado = ((30 + 5) * 5 > 100) And _
(52 > 200 / _
(2 + 5))
Código fuente 94

Uso de paréntesis para alterar la prioridad de operadores

Podemos alterar el orden natural de prioridades entre operadores utilizando los paréntesis, encerrando entre ellos los elementos que queramos sean resueltos en primer lugar dentro de una expresión. De esta forma, se resolverán en primer lugar las operaciones que se encuentren en los paréntesis más interiores, finalizando por las de los paréntesis exteriores. 
Es importante tener en cuenta, que dentro de los paréntesis se seguirá manteniendo la prioridad explicada anteriormente. El Código fuente 93 en condiciones normales, devolvería False como resultado. Sin embargo, gracias al uso de paréntesis, cambiamos la prioridad predeterminada, obteniendo finalmente True.

Dim Resultado As Boolean
Resultado = ((30 + 5) * 5 > 100) And (52 > 200 / (2 + 5)) ' devuelve: True
Código fuente 93

Prioridad entre operadores de distintos grupos.

Cuando una expresión contenga operadores de distintos grupos, estos se resolverán en el orden marcado por la Tabla 18.
El Código fuente 92 muestra un ejemplo de expresión en el que intervienen operadores de diferentes tipos.


Dim Resultado As Boolean
Resultado = 30 + 5 * 5 > 100 And 52 > 10 ' devuelve: False
Código fuente 92

Prioridad de operadores - II

Los operadores de comparación tienen todos la misma prioridad, resolviéndose en el orden de aparición dentro de la expresión. Los operadores lógicos se ajustan a la prioridad indicada en la Tabla 17.
En el ejemplo del Código fuente 91, el resultado final de la operación es True debido a que el operador Not cambia la segunda expresión a True, resultando las dos expresiones de la operación True.

Dim Resultado As Boolean
Resultado = 10 < 70 And Not 30 = 20 ' devuelve: True
Código fuente 91

Prioridad de operadores - I

Dentro de una línea de código que contenga varias operaciones, estas se resolverán en un orden predeterminado conocido como prioridad de operadores. Dicha prioridad se aplica tanto entre los operadores de un mismo grupo como entre los distintos grupos de operadores. 
Prioridad entre operadores del mismo grupo. Los operadores aritméticos se ajustan a la prioridad indicada en la Tabla 16
El operador de mayor prioridad es el de potenciación, los de menor son la suma y resta. En el caso de operadores con idéntica prioridad como multiplicación y división, se resolverán en el orden de aparición, es decir, de izquierda a derecha. Veamos un ejemplo en el Código fuente 90


Dim Resultado As Long
Resultado = 5 + 8 ^ 2 * 4 ' devuelve: 261
Código fuente 90