al0-e03 - equivalencias entre vb y cs estructuras modulares
DESCRIPTION
Equivalencias de sintaxis entre Algorítmica, Visual Basic y C#TRANSCRIPT
2012
Página 1
ENTREGA NÚMERO 03:
ESTRUCTURAS
MODULARES
1. Conversiones entre datos
2. Sobre los redondeos de Visual Basic
3. Parámetros opcionales (y sobrecargas)
4. Array de parámetros opcionales
5. Parámetros por valor y por referencia
1- Conversiones entre datos
En Visual Basic para .NET podemos usar muchas formas de convertir datos de
diferentes tipos, de hecho existen instrucciones propias para convertir entre tipos de
datos "elementales", por ejemplo del tipo Double o String a Integer. Para convertir
otros tipos de datos, existen ciertas instrucciones que nos permiten hacer esas
conversiones, aunque solo funcionará si la conversión es posible, por ejemplo, si
queremos convertir un tipo Cliente (definido por nosotros) en uno de tipo Empleado,
esto solo será posible si hay alguna relación directa (por herencia o implementación de
interfaces) entre esos dos tipos, o bien hemos definido alguna sobrecarga que permita
hacer esa conversión (esto solo es posible en Visual Basic 2005 o superior).
Pero no nos complicaremos mucho, y solo veremos cómo convertir datos de diferentes
tipos, y compararemos cómo sería el equivalente en C#. Ya que en C# no existen
instrucciones propias para hacer las conversiones, por el contrario, todas las
conversiones siempre se hacen de la misma forma.
Todo esto suponiendo que no estamos usando los métodos de la clase Convert, ya que
en ese caso, las conversiones se hacen de la misma forma en ambos lenguajes.
2012
Página 2
Como ya he comentado, en Visual Basic usaremos instrucciones, cómo usar esas
instrucciones, (y que parámetros permiten), tendrás que buscarlo en la ayuda de Visual
Studio, ya que aquí solo te mostraré "la idea" de cómo usarlas.
Visual Basic C#
Convertir a tipo entero (Integer):
<resultado> = CInt(<expresión>)
<resultado> = CType(<expresión>,
Integer)
<resultado> = (int)<expresión>
Convertir a tipo Double:
<resultado> = CDbl(<expresión>)
<resultado> = CType(<expresión>,
Double)
<resultado> = (double)<expresión>
Aquí te muestro solo dos casos, pero para el resto sería lo mismo, las otras instrucciones
de conversión son:
CBool, CByte, CChar, CDate, CDec, CLng, CObj, CSByte, CShort, CSng, CStr,
CUInt, CULng, CUShort.
Algunas de estas, como CSByte y las tres últimas, solo están disponibles en Visual
Basic 2005, ya que sirven para convertir a tipos que se definen por primera vez en esa
versión de Visual Basic.
En todos los casos siempre puedes usar CType(<expresión>, <tipo>) para realizar la
misma conversión.
Y como has visto en el código de C#, en ese lenguaje siempre se usa de la misma forma:
(<tipo>)<expresión>, es decir, encerrando entre paréntesis el tipo y anteponiéndolo a la
expresión a convertir.
En Visual Basic, además de CType, también podemos usar, (al menos para convertir
expresiones a tipos por referencia), las instrucciones DirectCast y TryCast. Si sabemos
que estamos trabajando con tipos por referencia estas últimas son preferibles a CType,
ya que tienen mejor rendimiento.
DirectCast en realidad sirva para convertir cualquier tipo de datos, pero siempre que
haya alguna relación de herencia o de implementación de interfaces.
TryCast, (que está disponible en Visual Basic 2005 y posterior), se usa solo con tipos
2012
Página 3
por referencia, y se usa normalmente comprobando si el valor que devuelve no es nulo
(Nothing).
En todas las conversiones, excepto con TryCast, si la conversión no se puede hacer, se
produce una excepción del tipo InvalidCastException, con TryCast, si no se puede
hacer la conversión "simplemente" se devuelve un valor nulo.
2- Sobre los redondeos de Visual Basic
Las funciones de conversión a enteros de Visual Basic siempre redondean usando el
llamado "redondeo bancario", tal como indica la documentación de Visual Studio,
comprobé que Visual Basic añade una llamada a Math.Round que C# no utiliza; por
tanto, si conviertes código de Visual Basic a C#, debes tener ese redondeo en cuenta, ya
que C# no redondea cuando se hace el "cast" o conversión con (int), mientras que
Visual Basic siempre lo hará, tanto con CType como con CInt.
Para que no haya comportamientos diferentes entre los dos lenguajes a la hora de hacer
conversiones, (ni redondeos "no deseados o controlados"), puedes usar las funciones de
conversión de la clase Convert, en el caso de convertir a un Integer (int en C#), tendrás
que usar Convert.ToInt32.
Con las conversiones de la clase Convert siempre se usa el redondeo bancario, se use
desde el lenguaje que se use.
3- Parámetros opcionales (y sobrecargas)
En Visual Basic, se pueden definir parámetros opcionales, usando la instrucción
Optional, en C# no hay equivalencia para esa instrucción, por tanto no se pueden
definir parámetros opcionales, al menos de la misma forma que en Visual Basic.
La única forma de definir parámetros opcionales en C# es usando un "array de
parámetros", pero eso lo verás en la siguiente sección.
Si te interesa que tu código de Visual Basic pueda convertirse fácilmente a C#, deberías
evitar el uso de parámetros opcionales con Optional. La solución es crear sobrecargas
2012
Página 4
de los métodos que reciban esos parámetros opcionales, que a la larga es casi lo mismo
y así no habrá conflictos entre los dos lenguajes.
Por ejemplo, si tienes este código de Visual Basic que usa Optional:
Public Shared Sub PruebaOptional(ByVal uno As Integer, _
Optional ByVal dos As Integer = 0, _
Optional ByVal tres As Boolean = True)
'...
End Sub
Lo puedes convertir a este otro, en el que se usan sobrecargas para tener las tres
posibilidades que nos da el código anterior:
Public Shared Sub PruebaOptional(ByVal uno As Integer)
PruebaOptional(uno, 0, True)
End Sub
Public Shared Sub PruebaOptional(ByVal uno As Integer, _
ByVal dos As Integer)
PruebaOptional(uno, dos, True)
End Sub
Public Shared Sub PruebaOptional(ByVal uno As Integer, _
ByVal dos As Integer, _
ByVal tres As Boolean)
'...
End Sub
Como ves, cuando definimos un parámetro con Optional, ese parámetro debe tener un
valor predeterminado, que será el que se use cuando no se indique, y eso es lo que
podemos hacer al definir las sobrecargas: llamamos al método que recibe todos los
parámetros, pero usando los que debería tener si no se indican esos parámetros.
Si usamos parámetros opcionales, estos deben aparecer después de los que no son
opcionales.
2012
Página 5
Lo que NO debes hacer es mezclar parámetros opcionales con sobrecargas, ya que en
algunos casos el propio compilador te indicará que algo anda mal en ese código porque
hay conflictos, ya que un parámetro Optional es opcional, pero también puede que se
indique al llamar al método, por tanto, en algunos casos no será opcional, sino que se
usará.
En C#, el código anterior de las sobrecargas, lo definiremos de esta forma:
public static void PruebaOptional(int uno) {
PruebaOptional(uno, 0, true);
}
public static void PruebaOptional(int uno, int dos) {
PruebaOptional(uno, dos, true);
}
public static void PruebaOptional(int uno, int dos, bool tres) {
//...
}
La ventaja de Optional o de las sobrecargas, es que podemos usar parámetros de
distintos tipos.
4- Array de parámetros opcionales
La alternativa de C# a los parámetros opcionales es usando un array de parámetros
opcionales, esto mismo también se puede hacer con Visual Basic.
Para definir un método que reciba un array de parámetros opcionales, en Visual Basic
usaremos la instrucción ParamArray, mientras que en C# usaremos params, en ambos
casos, después de esa instrucción hay que indicar un array del tipo de datos que
queramos usar internamente en el método.
En el siguiente código, los parámetros son de tipo entero y se devuelve la suma de todos
ellos como un valor de tipo Long.
2012
Página 6
Public Shared Function PruebaArrayOpcional( ByVal ParamArray datos()
As Integer) As Long
Dim total As Long = 0
For Each i As Integer In datos
total += i
Next
Return total
End Function
public static long PruebaArrayOpcional(params int[] datos)
{
long total = 0;
foreach( int i in datos )
{
total += i;
}
return total;
}
En Visual Basic, podemos usar la instrucción ParamArray junto con Optional, es
decir, podemos declarar parámetros Optional y parámetros con ParamArray, pero este
último debe aparecer después de todos los Optional que tengamos.
Tanto en Visual Basic como en C#, el array de parámetros opcionales debe estar
después de los parámetros que no son opcionales.
5- Parámetros por valor y por referencia
Y ya que estamos con el tema de los parámetros, veamos cómo definir los parámetros
por valor y por referencia. Además de cómo usarlos.
2012
Página 7
Tanto en Visual Basic para .NET como en C#, de forma predeterminada, los parámetros
son por valor, es decir, se pasa como argumento una copia del valor del parámetro. En
Visual Basic, se puede usar la instrucción ByVal para indicar que el parámetro es por
valor, de hecho, el propio IDE de Visual Basic siempre añade esa instrucción si no
indicamos nada.
Cuando nos interese que podamos modificar el valor de un parámetro, por ejemplo para
asignarle un nuevo valor, podemos usar los parámetros por referencia. En Visual Basic
se indican con la instrucción ByRef, y en C#, se pueden indicar de dos formas, usando
ref o bien usando out. La diferencia entre ref y out es que los argumentos pasados a
parámetros ref deben estar previamente iniciados, es decir, deben tener algún valor;
mientras que los parámetros out no es necesario que lo estén, y esa inicialización o
asignación, hay que hacerla en el propio método.
Nota:
No debemos confundir los parámetros por referencia con los tipos por referencia, ya que
un parámetro por referencia puede ser de un tipo por valor, como Integer o Double.
De hecho, cuando usamos tipos por referencia, no es necesario usar la instrucción
ByRef para poder modificar el contenido de ese parámetro, ya que al ser un tipo por
referencia, lo que se pasa es precisamente una referencia a la dirección de memoria en la
que está dicho objeto, por tanto siempre tendremos acceso al contenido.
Debido a la forma que Visual Basic trata las declaraciones de las variables, en teoría no
se podrían usar parámetros de tipo out, por tanto el equivalente más directo en C# es
ref. Pero ambos parámetros se pueden "simular" en Visual Basic por medio de ByRef.
A la hora de usar los métodos con parámetros por referencia, la diferencia entre los dos
lenguajes, es que en C# siempre tenemos que usar la instrucción out o ref que
corresponda con la definición del parámetro, mientras que en Visual Basic no se debe
usar la instrucción ByRef para usar un método que espere valores por referencia.
Veamos un método que recibe parámetros por valor y por referencia y cómo lo
definiríamos en los dos lenguajes:
Public Shared Sub PruebaRef(ByRef uno As Integer, ByVal dos As
Integer)
' Esta asignación afectará al parámetro
uno += dos
' Esta no afectará al valor usado como segundo argumento
dos = 999
End Sub
2012
Página 8
Public Shared Sub ProbandoRef()
Dim uno As Integer = 5
Dim dos As Integer = 2
Console.WriteLine("uno= {0}, dos = {1}", uno, dos)
PruebaRef(uno, dos)
Console.WriteLine("uno= {0}, dos = {1}", uno, dos)
End Sub
public static void PruebaRef(ref int uno, int dos)
{
// Esta asignación afectará al parámetro
uno += dos;
// Esta no afectará al valor usado como segundo argumento
dos = 999;
}
public static void ProbandoRef()
{
int uno = 5;
int dos = 2;
Console.WriteLine("uno= {0}, dos = {1}", uno, dos);
PruebaRef(ref uno, dos);
Console.WriteLine("uno= {0}, dos = {1}", uno, dos);
}
Como ves, en Visual Basic no hace falta indicar si el argumento se pasa a un parámetro
por referencia o no, sin embargo en C# es obligatorio indicar si ese parámetro es ref,
usando esa misma instrucción, si no lo hacemos, el compilador nos avisará que debemos
hacerlo.