Anda di halaman 1dari 29

Data Type Conversion, File Extensions

Converting between Data types


In Visual Basic, data can be converted in two ways: implicitly, which means the
conversion is performed automatically, and explicitly, which means you must perform
the conversion.
Implict Conversions
Let's understand implicit conversions in code. The example below declares two
variable, one of type double and the other integer. The double data type is assigned a
value and is converted to integer type. When you run the code the result displayed is
an integer value, in this case the value displayed is 132 instead of 132.31223.
Imports System.Console
Module Module1
Sub Main()
Dim d=132.31223 as Double
Dim i as Integer
i=d
WriteLine("Integer value is" & i)
End Sub
End Module
Explicit Conversions
When types cannot be implicitly converted you should convert them explicitly. This
conversion is also called as cast. Explicit conversions are accomplished using CType
function.
CType function for conversion
If we are not sure of the name of a particular conversion function then we can use the
CType function. The above example with a CType function looks like this:
Imports System.Console
Module Module1
Sub Main()
Dim d As Double
d = 132.31223
Dim i As Integer
i = CType(d, i)
'two arguments, type we are converting from, to type desired
WriteLine("Integer value is" & i)
End Sub

End Module
Below is the list of conversion functions which we can use in VB .NET.
CBool - use this function to convert to Bool data type
CByte - use this function to convert to Byte data type
CChar - use this function to convert to Char data type
CDate - use this function to convert to Date type
CDbl - use this function to convert to Double data type
CDec - use this function to convert to Decimal data type
CInt - use this function to convert to Integer data type
CLng - use this function to convert to Long data type
CObj - use this function to convert to Object type
CShort - use this function to convert to Short data type
CSng - use this function to convert to Single data type
CString - use this function to convert to String data type
Attributes
Attributes are those that lets us specify information about the items we are using in
VB .NET. Attributes are enclosed in angle brackets(< >) and are used when VB .NET
needs to know more beyond the standard syntax.
File Extensions in VB .NET
The files and their extensions which are created as part of the Windows Application
Project and their meaning are summarized below:
.vbproj->A Visual Basic project
Form1.vb->A form's code
AssemblyInfo.VB->Information about an assembly, includes version information
.vbproj.user->Stores project user options
.sln->Solution file which stores solution's configuration
.suo-> Stores Solution user options
Form1.resx.NET->XML based resource template
bin directory->Directory for binary executables
obj directory->Directory for debugging binaries
Language Terminology
Briefly on some terminology when working with the language:
Module: Used to hold code
Variable: A named memory location of a specific data type used to hold some value
Procedure: A callable series of statements which may or may not return a value
Sub-Procedure: A procedure with no return value
Function: A procedure with return value
Methods: A procedure built into the class
Constructor: Special method used to initialize and customize the object. It has the
same name as the class
Class: An OOP class which contains data and code

Object: An instance of a class


Arrays: Programming constructs that lets us access data by numeric index
Attributes: They are the items that specify information about other items being used in
VB. NET

Equivalencias entre Visual


Basic y C# (3)
Publicado el 06/Ago/2006
Actualizado el 06/Ago/2006
Esta es la tercera pgina con equivalencias de las instrucciones entre los dos lenguajes ms
usados de .NET Framework: Visual Basic para .NET y C#. En las pginas anteriores (primera
y segunda) puedes encontrar ms equivalencias y algunas consideraciones que debes tener
en cuenta a la hora de convertir cdigo de Visual Basic a C# o viceversa.

Estas son las equivalencias publicadas en esta pgina:


1. Select Case / switch
2. Conversiones entre datos
3. Sobre los redondeos de Visual Basic
4. Parmetros opcionales (y sobrecargas)
5. Array de parmetros opcionales
6. Parmetros por valor y por referencia

1- Select Case / switch


Pues s, esta se me pas totalmente... por suerte hay gente que te recuerda
las cosas, je, je.
En esta ocasin ha sido Eugenio Estrada, que aunque l ya lo ha publicado,
pues... en fin... creo que es conveniente que estn todas en un mismo sitio
para que resulte ms fcil.
En realidad esta "equivalencia" debera estar en la primera pgina de
equivalencias, pero como ha pasado ya mucho tiempo desde su publicacin...
pues... he preferido publicarla en una nueva, as te pongo algunas cosillas
ms.
Para "justificar" el retraso de ms de tres aos, te pongo algunas cosillas ms
que debes tener en cuenta sobre esta instruccin, que como podrs comprobar
es mucho ms potente en Visual Basic que en C#, aunque debemos ser

precavidos a la hora de usar esa funcionalidad extra, tal como te comento ms


abajo.
Visual Basic
Select Case <condicin>
Case <opcin 1>

C#
switch (<condicin>)
{

'...

case <opcin 1>:

Case <opcin 2>

//...

'...

break;

Case Else

case <opcin 2>:

'...

//...
break;

End Select

default:
//...
break;
}

En C# los valores de las opciones case deben ser valores constantes, no se


permiten expresiones ni variables, adems de que solo se puede indicar un valor
en cada "case", aunque se pueden indicar varios case para contemplar ms de un
valor para ejecutar el cdigo de un mismo bloque.
En Visual Basic se permiten expresiones y para ello existen instrucciones que
podemos indicar en cada bloque Case.
La condicin, tanto en VB como en C#, puede ser una expresin.
Select Case <expresin con valor
entero>
Case 1

switch (<expresin con valor


entero>)
{

'...

case 1:

Case 2, 3, 4

//...

'...

break;

Case Else

case 2:

'...

case 3:

End Select

case 4:
//...

' Tambin de esta forma

break;

Select Case <expresin con valor


entero>

default:
//...

Case 1
'...
Case 2 To 4

break;
}

'...
Case Else
'...
End Select

Adems en Visual Basic se pueden usar varios valores en cada Case, separndolos
con comas, y esos valores pueden ser expresiones de cualquier tipo, adems de
poder usarse variables, etc., es decir, cualquier cosa que produzca un valor del
tipo esperado.
En Visual Basic, para indicar valores que requieran los operadores de comparacin
debemos usar Is, por ejemplo, para indicar que el valor sea mayor que 7, lo
haremos con: Case Is > 7.
Y si queremos que est dentro de un rango de valores, podemos usar To, en el
ejemplo anterior hemos usado 2 To 4 para indicar los valores entre 2 y 4, pero
tambin podemos combinar varias expresiones, por ejemplo:
Case 2 To 4, 9 To 12, Is > 99, Is < 299
En este caso se tendran en cuenta todos los valores posibles indicados en esas
expresiones. Como puedes comprobar, no podremos usar los operadores And, Or,
etc., en su caso podemos usar varios Is.

ATENCIN:
Si usas Is < 299 debes tener en cuenta que esa condicin se evala de
forma independiente de las dems, por tanto el caso anterior, (si solo
quieres valores hasta 299), lo puedes escribir solo con la ltima
condicin:
Case Is < 299
Ya que si no cumple ninguna de las anteriores, se evaluar esa, por tanto,
si, por ejemplo, el valor de la condicin indicada en Select Case fuese 8,
tambin se evaluara, ya que es menor de 299.
Pero el "problema" va a ms y en el ejemplo Case 2 To 4, 9 To 12, Is >
99, Is < 299, en realidad "capturar" cualquier valor, ya que si se
cumple el Is > 99 tambin se capturarn valores mayores de 298.
Por tanto, aunque en un Case puedas poner varias expresiones, debes
ser consciente de que es lo que "realmente" ests haciendo... y no
"pensar" que es lo que "supuestamente" ests haciendo.

Por ltimo decir que como en Visual Basic los dos puntos se utilizan como
separador de instrucciones en una misma lnea, podemos usar los dos puntos
para separar instrucciones Case, estn o no en la misma lnea.
Case 2:
Case 3:
Case 2 : Case 3
Otra cosa a tener en cuenta (adems de la advertencia anterior), es que cada

sentencia Case solo se evaluar despus de las que haya antes.

2- 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 conversin 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
relacin directa (por herencia o implementacin de interfaces) entre esos dos
tipos, o bien hemos definido alguna sobrecarga que permita hacer esa
conversin (esto solo es posible en Visual Basic 2005 o superior).
Pero no nos complicaremos mucho, y solo veremos cmo convertir datos de
diferentes tipos, y compararemos cmo sera 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 mtodos de la clase
Convert, ya que en ese caso, las conversiones se hacen de la misma forma en
ambos lenguajes.
Como ya he comentado, en Visual Basic usaremos instrucciones, cmo usar
esas instrucciones, (y que parmetros permiten), tendrs que buscarlo en la
ayuda de Visual Studio, ya que aqu solo te mostrar "la idea" de cmo
usarlas.
Visual Basic

C#

Convertir a tipo entero (Integer):


<resultado> = CInt(<expresin>)

<resultado> = (int)<expresin>

<resultado> = CType(<expresin>,
Integer)

Convertir a tipo Double:


<resultado> = CDbl(<expresin>)

<resultado> = CType(<expresin>,

<resultado> = (double)<expresin>

Double)

Aqu te muestro solo dos casos, pero para el resto sera lo mismo, las otras
instrucciones de conversin 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 estn disponibles en
Visual Basic 2005, ya que sirven para convertir a tipos que se definen por
primera vez en esa versin de Visual Basic.
En todos los casos siempre puedes usar CType(<expresin>, <tipo>) para
realizar la misma conversin.
Y como has visto en el cdigo de C#, en ese lenguaje siempre se usa de la
misma forma: (<tipo>)<expresin>, es decir, encerrando entre parntesis el
tipo y anteponindolo a la expresin a convertir.
En Visual Basic, adems de CType, tambin 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 relacin de herencia o de implementacin de
interfaces.
TryCast, (que est disponible en Visual Basic 2005 y posterior), se usa solo
con tipos 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 conversin no se puede
hacer, se produce una excepcin del tipo InvalidCastException, con
TryCast, si no se puede hacer la conversin "simplemente" se devuelve un
valor nulo.

3- Sobre los redondeos de Visual Basic


Comprobando el cdigo de nmeros a letras que mi amigo Harvey Triana ha
publicado en las colaboraciones, y despus de proponerle unos cambios al
cdigo de Visual Basic, (el de C# no llegu a probarlo), me coment que el
cdigo de C# funcionaba correctamente.
A pesar de las calores de este mes de Agosto, me entr curiosidad, y pude
comprobar que el comportamiento de las conversiones a entero de C# y Visual
Basic eran diferentes, y por tanto, no siempre producan el mismo valor, al
menos usando las "instrucciones" equivalentes que te he comentado antes, en
el caso de C# con (int) y en el de Visual Basic con CType(..., Integer).
Me puse a examinar un poco el cdigo IL generado por las dos clases, y para
mi extraeza, (aunque en el fondo saba que lo haca, ya que las funciones de
conversin a enteros de Visual Basic siempre redondean usando el llamado

"redondeo bancario", tal como indica la documentacin de Visual Studio),


comprob que Visual Basic aade una llamada a Math.Round que C# no
utiliza; por tanto, si conviertes cdigo de Visual Basic a C#, debes tener ese
redondeo en cuenta, ya que C# no redondea cuando se hace el "cast" o
conversin 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 conversin de la clase Convert, en el caso de convertir a
un Integer (int en C#), tendrs 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.

4- Parmetros opcionales (y sobrecargas)


En Visual Basic, se pueden definir parmetros opcionales, usando la instruccin
Optional, en C# no hay equivalencia para esa instruccin, por tanto no se
pueden definir parmetros opcionales, al menos de la misma forma que en
Visual Basic.
La nica forma de definir parmetros opcionales en C# es usando un "array de
parmetros", pero eso lo vers en la siguiente seccin.
Si te interesa que tu cdigo de Visual Basic pueda convertirse fcilmente a C#,
deberas evitar el uso de parmetros opcionales con Optional. La solucin es
crear sobrecargas de los mtodos que reciban esos parmetros opcionales, que
a la larga es casi lo mismo y as no habr conflictos entre los dos lenguajes.
Por ejemplo, si tienes este cdigo 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 cdigo 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 parmetro con Optional, ese parmetro 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 mtodo
que recibe todos los parmetros, pero usando los que debera tener si no se
indican esos parmetros.
Si usamos parmetros opcionales, estos deben aparecer despus de los que no
son opcionales.
Lo que NO debes hacer es mezclar parmetros opcionales con sobrecargas, ya
que en algunos casos el propio compilador te indicar que algo anda mal en
ese cdigo porque hay conflictos, ya que un parmetro Optional es opcional,
pero tambin puede que se indique al llamar al mtodo, por tanto, en algunos
casos no ser opcional, sino que se usar.
En C#, el cdigo 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


parmetros de distintos tipos.

5- Array de parmetros opcionales


La alternativa de C# a los parmetros opcionales es usando un array de
parmetros opcionales, esto mismo tambin se puede hacer con Visual Basic.
Para definir un mtodo que reciba un array de parmetros opcionales, en
Visual Basic usaremos la instruccin ParamArray, mientras que en C#
usaremos params, en ambos casos, despus de esa instruccin hay que
indicar un array del tipo de datos que queramos usar internamente en el
mtodo.
En el siguiente cdigo, los parmetros son de tipo entero y se devuelve la
suma de todos ellos como un valor de tipo Long.
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 instruccin ParamArray junto con Optional,


es decir, podemos declarar parmetros Optional y parmetros con

ParamArray, pero este ltimo debe aparecer despus de todos los Optional
que tengamos.
Tanto en Visual Basic como en C#, el array de parmetros opcionales debe
estar despus de los parmetros que no son opcionales.

6- Parmetros por valor y por referencia


Y ya que estamos con el tema de los parmetros, veamos cmo definir los
parmetros por valor y por referencia. Adems de cmo usarlos.
Tanto en Visual Basic para .NET como en C#, de forma predeterminada, los
parmetros son por valor, es decir, se pasa como argumento una copia del
valor del parmetro. En Visual Basic, se puede usar la instruccin ByVal para
indicar que el parmetro es por valor, de hecho, el propio IDE de Visual Basic
siempre aade esa instruccin si no indicamos nada.
Cuando nos interese que podamos modificar el valor de un parmetro, por
ejemplo para asignarle un nuevo valor, podemos usar los parmetros por
referencia. En Visual Basic se indican con la instruccin 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 parmetros ref deben estar
previamente iniciados, es decir, deben tener algn valor; mientras que los
parmetros out no es necesario que lo estn, y esa inicializacin o asignacin,
hay que hacerla en el propio mtodo.

Nota:
No debemos confundir los parmetros por referencia con los
tipos por referencia, ya que un parmetro 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 instruccin ByRef para poder modificar el contenido de
ese parmetro, ya que al ser un tipo por referencia, lo que se
pasa es precisamente una referencia a la direccin 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
teora no se podran usar parmetros de tipo out, por tanto el equivalente ms
directo en C# es ref. Pero ambos parmetros se pueden "simular" en Visual
Basic por medio de ByRef.
A la hora de usar los mtodos con parmetros por referencia, la diferencia
entre los dos lenguajes, es que en C# siempre tenemos que usar la instruccin

out o ref que corresponda con la definicin del parmetro, mientras que en
Visual Basic no se debe usar la instruccin ByRef para usar un mtodo que
espere valores por referencia.
Veamos un mtodo que recibe parmetros por valor y por referencia y cmo lo
definiramos en los dos lenguajes:
Public Shared Sub PruebaRef(ByRef uno As Integer, ByVal dos As
Integer)
' Esta asignacin afectar al parmetro
uno += dos
' Esta no afectar al valor usado como segundo argumento
dos = 999
End Sub

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 asignacin afectar al parmetro
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


parmetro por referencia o no, sin embargo en C# es obligatorio indicar si ese
parmetro es ref, usando esa misma instruccin, si no lo hacemos, el
compilador nos avisar que debemos hacerlo.

Curso de iniciacin a la
programacin
con Visual Basic .NET
Entrega nmero siete, (06/Dic/2002)
Publicada el 06/Dic/2002

En esta entrega veremos otra forma con la que podemos escoger entre varias opciones.
Hasta ahora hemos usado las instrucciones IF / Then / Else, pero Visual Basic pone a
nuestra disposicin la instruccin Select Case con la que podemos elegir entre varias
opciones y en la versin .NET nos facilita un poco las cosas, al menos con respecto a como
se usaba en las versiones anteriores de Visual Basic, esto lo comprobaremos en cuanto
veamos una nueva forma de crear constantes.
Empecemos con la instruccin Select Case.
Esta instruccin se usa de la siguiente forma:
Select Case <expresin a evaluar>
Case <lista de expresiones>
' ...
Case <otra lista de expresiones>
' ...
Case Else
' si no se cumple ninguna de las listas de expresiones
End Select
Despus de Select Case se pondr una expresin a evaluar, es decir lo que queremos
comprobar si se cumple o no, esto es lo mismo que hacemos con el If <expresin a
evaluar> Then; lo que diferencia al Select Case del If... Then es que con el If... Then si
queremos hacer varias comprobaciones, tendremos que usar diferentes If... Then con varios
ElseIf..., mientras que con el Select Case, cada una de las cosas que queremos comprobar lo
ponemos en los distintos Case... cmo? que no te enteras?, vale, vemoslo con un
ejemplo.
Supongamos que queremos comprobar si el contenido de la variable i tiene distintos valores
y segn esos valores tendremos que hacer una cosa u otra.
Si lo hiciramos usando If... Then, tendramos que escribir algo como esto:

If i = 3 Then
'
ElseIf i > 5 AndAlso i < 12 Then
'
ElseIf i = 14 OrElse i = 17 Then
'
ElseIf i > 25 Then
'
Else
'
End If

Esto mismo, con Select Case lo haramos de esta forma:


Select Case i
Case 3
'
Case 6 To 11
'
Case 14, 17
'
Case Is > 25
'
Case Else
'
End Select

Como podemos comprobar, despus de Select Case ponemos lo que queremos tener en
cuenta, en este caso es el contenido de la variable i, cuando queremos comprobar si es igual
a 3, simplemente ponemos el 3, lo mismo hacemos cuando queremos hacer algo para el
caso de que el valor sea 14 o 17, pero en este caso simplemente especificamos los valores
que queremos comprobar separados por comas, podemos poner tantos como necesitemos.
Si queremos comprobar un rango de valores, por ejemplo que el valor de i estuviera entre 5
y 12 (mayor que 5 y menor que 12), podemos hacerlo de esta forma: usamos 6 To 11, es
decir queremos que esa condicin se cumpla cuando el valor de i tenga un valor de 6 a 11.
Cuando queremos comprobar si el valor es mayor (o cualquier otra comprobacin),
usaremos Is, como en el caso de Is > 25, esto es lo mismo que comprobar si i es mayor que
25.

Por ltimo, si ninguno de esos casos se cumple, se ejecutar lo que est a continuacin de
Case Else, que funciona igual que el Else ltimo que tenemos en el bloque If... Then.
Como vemos, funciona casi igual que con If... Then, pero de una forma algo ms ordenada,
la nica pega es que slo podemos evaluar una expresin, mientras que con If podemos
usar tantas como queramos... precisamente por eso existen estas dos posibilidades... cuando
una no es vlida, podemos usar la otra.
Adems de expresiones simples, en Select Case podemos indicar cualquier expresin
vlida, siempre que el resultado de esa expresin sea comparable con un valor, el cual, a su
vez, producir un valor verdadero o falso.
Estas expresiones, pueden ser tanto numricas como de cadenas de caracteres.
No voy a dar ahora ms ejemplos, ya que a lo largo de este curso de iniciacin a la
programacin de Visual Basic .NET tendremos ocasin de ver ms de un ejemplo del uso
de Select Case (e incluso de If... Then), as que no te impacientes y si quieres ver ejemplos
de Select Case, te invito a que le eches una ojeada a la documentacin de Visual Studio
.NET, que es bastante amplia y en algunos casos, hasta fcil de comprender... (bueno, slo
en algunos casos, ya que si siempre fuese tan "clara", para que escribir nada que lo
aclare...?)
Bien, sigamos nuestro aprendizaje, ahora vamos a ver esa otra forma de crear constantes
que mencion al principio.
Me estoy refiriendo a:

Las enumeraciones (Enum)


Como habrs podido ver en la descripcin del glosario (si es que has seguido el link o
enlace de la lnea anterior), una enumeracin es un tipo especial de variable numrica en la
que los valores que dicha variable puede tomar, son constantes simblicas, es decir que en
lugar de usar un nmero, se usa una palabra (constante) que hace referencia a un nmero.
Por ejemplo, (si mejor pon un ejemplo, que si no, no hay quien te entienda), si queremos
tener una variable llamada color la cual queremos que contenga un valor numrico que
haga referencia a un color en particular, es que en lugar de usar el valor 1, 2 3, queremos
usar la constante rojo, azul, verde, etc. Esto lo haramos de esta forma:
Enum colores
rojo = 1
azul
verde
End Enum

Las declaraciones de las enumeraciones hay que hacerla fuera de cualquier procedimiento,
por ejemplo dentro de una clase o un mdulo, pero tambin pueden estar declarados dentro
de un espacio de nombres, todo depender de la cobertura (o amplitud de acceso) que

queramos darle. Adems podemos poder darle las propiedades pblica, privada, etc., como
siempre, esto influir en los sitios desde los que podemos usar esa enumeracin.
Los valores que pueden tener los miembros de una enumeracin, pueden ser cualquiera de
los que un tipo numrico de tipo entero pueda tener. Por defecto el tipo es Integer, pero las
enumeraciones tambin pueden ser de tipo Byte, Long o Short, para poder especificar un
tipo diferente a Integer, lo indicaremos usando As Tipo despus del nombre de la
enumeracin.
Por defecto, el primer valor que tendr un elemento de una enumeracin ser cero y los
siguientes elementos, salvo que se indique lo contrario, tendrn uno ms que el anterior.
En el ejemplo mostrado, el elemento rojo, valdr 1, azul valdr 2 y verde tendr un valor 3.
Para poder cambiar esos valores automticos, podemos indicarlo usando una asignacin
como la usada para indicar que rojo vale 1: rojo = 1
En caso de que no indiquemos ningn valor, el primero ser cero y los siguientes valdrn
uno ms que el anterior, por ejemplo, si la declaracin anterior la hacemos de esta forma:
Enum colores
rojo
azul
verde
End Enum

rojo valdr 0, azul ser igual a 1 y verde tendr el valor 2.


La asignacin podemos hacerla en cualquier momento, en el siguiente caso, rojo valdr
cero, azul tendr el valor 3 y verde uno ms que azul, es decir 4.
Enum colores
rojo
azul = 3
verde
End Enum

Por supuesto, los valores que podemos asignar a los elementos (o miembros) de una
enumeracin sern valores que estn de acuerdo con el tipo de datos, recordemos que si no
indicamos nada, sern de tipo Integer, pero si especificamos el tipo de datos, por ejemplo,
de tipo Byte, el cual si recordamos la tabla vista en la cuarta entrega, slo podr contener
valores enteros comprendidos entre 1 y 255. Sabiendo esto, no podramos declarar la
siguiente enumeracin sin recibir un mensaje de error:
Enum colores As Byte
azul = 255

rojo
verde
End Enum

Por qu? te preguntars, si el valor est dentro de los valores permitidos?


Por la sencilla razn de que azul tiene un valor adecuado, pero tanto rojo como verde,
tendrn un valor 256 y 257 respectivamente, los cuales estn fuera del rango permitido por
el tipo Byte.

Figura 1. Los valores de los miembros de las enumeraciones


deben estar comprendidos en el rango del tipo usado.
Otra cosa con la que tendremos que andarnos con cuidado al usar las enumeraciones, es que
una variable declarada del tipo de una enumeracin, en teora no debera admitir ningn
valor que no est incluido en dicha enumeracin, aunque esta restriccin es slo
"recomendable", no es algo "obligatorio", aunque si tenemos activado Option Strict On, el
IDE de Visual Studio .NET nos lo recordar, con lo cual nos obligar a hacer una
conversin de datos entre la variable (o el valor usado) y el tipo "correcto" al que
corresponde la enumeracin.
Para entenderlo mejor, veamos un ejemplo:
Dim unColor As colores
'
unColor = 1

Aunque el valor 1, sea un valor correcto, si tenemos Option Strict On, nos indicara que no
se permite la conversin implcita entre Integer y el tipo colores. Si no tuviramos activada
la comprobacin estricta, (cosa que yo te recomiendo y si pudiera, hasta te obligara a usar,
ms que nada porque as aprenders a hacer las cosas bien, que siempre habr tiempo de
hacerlas mal), a lo que iba, si no tuvieras esa opcin activada, no te mostrara ningn error,
pero si sabemos que para un buen uso de los tipos de datos, deberamos hacer la conversin
correspondiente, por qu no hacerla?
Si te portas como el Guille quiere, tendras que hacer lo siguiente:
unColor = CType(1, colores)

Es decir, usamos CType para hacer la conversin entre el nmero y el tipo correcto de
datos.
De todas formas, te dir que si usas el IDE de Visual Studio .NET, ste te mostrar los
valores que puedes asignarle a la variable declarada del tipo colores:

Figura 2. Las variables del tipo de una enumeracin slo


deberan tener los valores de dicha enumeracin
Al igual que ocurre con las variables de tipo Boolean, (que slo pueden tomar los valores
True o False), cuando vamos a asignar un valor, se nos muestra los valores posibles, esto
mismo tambin ocurre si queremos usar esa variable en en una comparacin o en un Select
Case, a esto es a lo que me refera al principio de esta entrega.
Veamos lo que nos mostrara el IDE al usar la variable unColor en los casos antes
mencionados:

Una enumeracin en una comparacin If

Una variable enumerada en un Select Case

En las versiones anteriores de Visual Basic, podamos usar los miembros de las
enumeraciones sin indicar la enumeracin a la que pertenecen, por ejemplo, podamos
asignar el valor azul a una variable del tipo colores, pero en Visual Basic .NET esto ya no
es posible, si queremos usar el miembro azul, tenemos que indicar la enumeracin a la que
pertenece, por ejemplo con unColor = colores.azul, esto ms que un inconveniente es una
ventaja, ya que as no habr posibilidades de "mal interpretacin" o mal uso de los
miembros de una enumeracin.
Como he mencionado antes, deberamos hacer la comprobacin correspondiente para saber
si el valor que estamos asignando a una variable "enumerada" es el adecuado o no, por
ejemplo, si el parmetro de un procedimiento recibe un tipo enumerado, puede ser que el
valor con el que se llame a ese procedimiento no sea un valor vlido, cmo podemos
evitar estos casos?
En principio podramos hacer una comprobacin, bien usando comparaciones If o, mejor
an, usando Select Case, para el caso de la enumeracin colores no habra mucho
problema, ya que slo tiene tres valores y esa comprobacin podra quedar de esta forma:
Private Sub pruebaColores(ByVal elColor As colores)
Select Case elColor
Case colores.azul, colores.rojo, colores.verde
' OK
Case Else
' si no es ninguno de los vlidos,
' asignamos uno por defecto
elColor = colores.azul
End Select
' resto del cdigo...
End Sub

Esto est bien, ya que, a pesar de que usemos CType para convertir un valor en la
enumeracin, no evita que que se "cuele" un valor errneo:

pruebaColores(CType(12, colores))

Esta llamada sera correcta, pero el valor no estara dentro de los valores vlidos, aunque no
producira ningn tipo de error, ya que, aunque 12 no sea un valor vlido del tipo colores, si
que es un valor vlido del tipo Integer, que al fin y al cabo es el tipo de valores que admiten
las variables declaradas como colores.
En el procedimiento, se comprueba si el valor pasado en el parmetro es del tipo adecuado
y se actuara de la forma que nosotros quisiramos. El problema vendra si la cantidad de
miembros de la enumeracin fuese muy extensa y esos valores no fuesen consecutivos, ya
que nos obligara a hacer muchas "comparaciones" para poder saber si el valor indicado es
uno de los valores correctos.
Para poder solventar este "problemilla", tendremos que echar mano del propio .NET
Framework, en particular de la clase Enum, esta clase tiene una serie de mtodos
"estticos" que podemos usar para distintas circunstancias, en nuestro caso particular,
podemos usar el mtodo IsDefined que devolver un valor verdadero o falso, segn el
valor indicado est o no definido en la enumeracin.
Por ejemplo si hacemos esto:
If System.Enum.IsDefined(unColor.GetType, 12) Then
o esto otro, que para el caso es lo mismo, ya que el primer parmetro de esta funcin espera
un tipo:
If System.Enum.IsDefined(GetType(colores), 12) Then
Se devolver un valor falso, ya que 12 no es miembro de la enumeracin colores.
En el primer caso usamos la variable del tipo colores (unColor) y usamos el mtodo
GetType para saber que tipo de datos es esa variable y en el segundo ejemplo, usamos la
funcin GetType para averiguar el tipo del parmetro indicado.
Veamos el cdigo del procedimiento pruebaColores usando este nuevo sistema de
averiguar si un valor es o no correcto (o vlido) para la enumeracin indicada.
Private Sub pruebaColores(ByVal elColor As colores)
If System.Enum.IsDefined(elColor.GetType, elColor) = False Then
elColor = colores.azul
Console.WriteLine("el valor no es correcto")
Else
Console.WriteLine("valor correcto")
End If
' resto del cdigo...
End Sub

Aunque no debes preocuparte demasiado, al menos por ahora, si no llegas a entender todo
esto que estamos viendo, simplemente "acepta" que funciona y ms adelante te das una
vueltecita por esta entrega y seguro que lo comprenders mejor. De todas formas, te voy a

explicar con ms o menos detalle que es lo que se hace en este procedimiento.


La funcin IsDefined espera dos parmetros, el primero es el tipo de una enumeracin,
todos los objetos de .NET Framework tienen el mtodo GetType que indica ese tipo de
datos, en este caso usamos la variable elColor (que es del tipo colores) y mediante el
mtodo GetType, indicamos el dato que esa funcin espera. En el segundo parmetro, hay
que indicar un valor que ser el que se compruebe si est o no definido en dicha
enumeracin, si ese valor es uno de los incluidos en la enumeracin indicada por GetType,
la funcin devolver True, en caso de que no sea as, devolver un valor False.
Adems de IsDefined, la clase Enum tiene otros mtodos que pueden sernos tiles. Pero en
lugar de enumerrtelos aqu, dejar que le eches un vistazo a la documentacin del .NET
Framework (o de Visual Studio .NET), para que practiques en el uso de dicha
documentacin...
(Guille, no seas malo, anda, dale aunque sea un par de ejemplos, bueno, pero es que si no,
no leen la documentacin y as... pues no aprenden...)
Valeee, est bien, veamos algunos de los mtodos de la clase Enum: (que hay que usar con
el System. delante para que el VB no se confunda con el "intento" de una declaracin del
tipo Enum)
GetName, indica el nombre con el que se ha declarado el miembro de la enumeracin, por
ejemplo, en el ejemplo de la enumeracin colores mostrada en la figura 2, el valor 1, sera
azul:
System.Enum.GetName(unColor.GetType, 1)
En caso de que el valor indicado no pertenezca a la enumeracin, devolver una cadena
vaca.
Tambin se pude obtener el "nombre" del miembro usando ToString: unColor.ToString
GetNames, devuelve un array de tipo String con los nombres de todos los miembros de la
enumeracin.
Lo que es un array lo veremos en detalle en otra ocasin, pero espero que puedas
comprender qu es lo que hace el siguiente cdigo sin que te de un "dolor" de cabeza.
Dim a() As String = System.Enum.GetNames(unColor.GetType)
Dim i As Integer
For i = 0 To a.Length - 1
Console.WriteLine("el valor {0} es {1}", i, a(i))
Next

GetValues, devuelve un array con los valores de los miembros de la enumeracin.


El tipo devuelto es del tipo Array, que en realidad no es un array (o matriz) de un tipo de
datos especfico, sino ms bien es el tipo de datos en el que se basan los arrays o matrices.
Dim a As Array = System.Enum.GetValues(unColor.GetType)
For i = 0 To a.Length - 1

Console.WriteLine("el valor {0} es {1}", i, a.GetValue(i))


Next

Por ltimo vamos a ver un mtodo que, casi con toda seguridad veremos en ms de una
ocasin:
Parse, devuelve un valor de tipo Object con el valor de la representacin de la cadena
indicada en el segundo parmetro. Esa cadena puede ser un valor numrico o una cadena
que representa a un miembro de la enumeracin.
System.Enum.Parse(unColor.GetType, "1")
System.Enum.Parse(unColor.GetType, "azul")

Hay ms mtodos, pero creo que estos que acabo de enumerar son los ms interesantes, de
todas formas, te invito a seguir investigando por tu cuenta... cosa que, aunque yo no te lo
dijera, deberas acostumbrarte a hacer.
Pero ya que estamos con esto de Parse y para ir terminando esta entrega, veamos cmo
podemos usar ese mtodo para los tipos de datos que podemos usar en .NET Framework
(los cuales vimos en la cuarta entrega).
El mtodo Parse se utiliza para convertir una cadena en un valor numrico, el tipo de
nmero devuelto depender del tipo desde el que hemos usado ese mtodo, por ejemplo si
hacemos lo siguiente:
Dim s As String = "123"
Dim i As Integer = Integer.Parse(s)

El valor asignado a la variable numrica i, sera el valor 123 que es un nmero entero
vlido.
Pero si hacemos esto otro:
Dim b As Byte = Byte.Parse(s)

Tambin se asignara el valor 123 a la variable b, que es de tipo Byte, pero el nmero 123
ya no es un nmero entero, sino del tipo byte... esto es claro, dirs, pero, si el valor
guardado en la variable s no estuviese dentro del "rango" de valores aceptados por el tipo
Byte, esto producira una excepcin (o error).
s = "129.33"
i = Integer.Parse(s)

En este caso, el error se produce porque 129.33 no es un nmero entero vlido, por tanto,
cuando usemos Parse, o cualquiera de las funciones de conversin, tendremos que tener
cuidado de que el valor sea el correcto para el tipo al que queramos asignar el valor...
Cmo solucionar este pequeo inconveniente?
No perdindote la prxima entrega de este Curso de Iniciacin a la Programacin con
Visual Basic .NET, ya que esta entrega se acaba aqu, as que... a esperar... que remedio!
Pero no te preocupes que no tendrs que esperar mucho... (al menos intentar que sea antes
de que acabe este "pedazo" de puente de la Constitucin que empez hoy da 6 y que dura
hasta el lunes da 9)
Veamos las cosillas que hemos visto en esta sptima entrega:
Hemos visto cmo elegir entre varias opciones mediante Select Case, tambin sabemos
cmo crear enumeraciones o constantes simblicas que estn relacionadas de alguna forma,
tambin hemos visto algunos mtodos de la clase Enum con los que podemos saber si un
valor pertenece a los definidos en la enumeracin o con los que podemos saber los nombres
de los miembros de dicha enumeracin, adems de saber cmo podemos convertir cadenas
de caracteres en un valor numrico, mediante el mtodo Parse.
Para la prxima entrega veremos cmo detectar o interceptar errores y algunas otras
cosillas, como el tema que tambin hemos tratado, aunque slo haya sido de pasada, sobre
los arrays o matrices.

Nos vemos.
Guillermo
Cdigo Fuente:
/*
* Created by SharpDevelop.
* User: Santos
* Date: 14/11/2005
* Time: 04:41 p.m.
*
* To change this template use Tools | Options | Coding | Edit Standard
Headers.
*/
using System;
using System.Windows.Forms;

namespace Cantidad_a_Letra
{

public class CantidadLetra


{
private string[] sUnidades = {"", "un", "dos", "tres",
"cuatro", "cinco", "seis", "siete", "ocho", "nueve", "diez",
"once", "doce", "trece", "catorce", "quince", "dieciseis",
"diecisiete", "dieciocho", "diecinueve", "veinte",
"veintin", "veintidos", "veintitres", "veinticuatro",
"veinticinco", "veintiseis", "veintisiete", "veintiocho", "veintinueve"};

private string[] sDecenas = {"", "diez", "veinte",


"treinta", "cuarenta", "cincuenta", "sesenta", "setenta", "ochenta",
"noventa"};

private string[] sCentenas = {"", "ciento", "doscientos",


"trescientos", "cuatrocientos", "quinientos", "seiscientos",
"setecientos", "ochocientos", "novecientos"};

private string sResultado = "";

public string ConvertirCadena (string sNumero) {


double dNumero;
double dNumAux = 0;
char x;
string sAux;

sResultado = " ";


try {
dNumero = Convert.ToDouble (sNumero);
}
catch {
return "";
}

if (dNumero > 999999999999)


return "";

if (dNumero > 999999999) {


dNumAux = dNumero % 1000000000000;
sResultado += Numeros (dNumAux, 1000000000)
+ " mil ";
}

if (dNumero > 999999) {


dNumAux = dNumero % 1000000000;
sResultado += Numeros (dNumAux, 1000000) +
" millones ";
}

if (dNumero > 999) {


dNumAux = dNumero % 1000000;
sResultado += Numeros (dNumAux, 1000) + "
mil ";
}

dNumAux = dNumero % 1000;


sResultado += Numeros (dNumAux, 1);

//Enseguida verificamos si contiene punto, si es


as, los convertimos a texto.
sAux = dNumero.ToString();

if (sAux.IndexOf(".") >= 0)
sResultado += ObtenerDecimales (sAux);

//Las siguientes lneas convierten el primer


caracter a mayscula.
sAux = sResultado;
x = char.ToUpper (sResultado[1]);

sResultado = x.ToString ();

for (int i = 2; i<sAux.Length; i++)


sResultado += sAux[i].ToString();

return sResultado;
}

public string ConvertirCadena (double dNumero) {


double dNumAux = 0;
char x;
string sAux;

sResultado = " ";

if (dNumero > 999999999999)


return "";

if (dNumero > 999999999) {


dNumAux = dNumero % 1000000000000;
sResultado += Numeros (dNumAux, 1000000000)
+ " mil ";
}

if (dNumero > 999999) {


dNumAux = dNumero % 1000000000;
sResultado += Numeros (dNumAux, 1000000) +
" millones ";
}

if (dNumero > 999) {


dNumAux = dNumero % 1000000;
sResultado += Numeros (dNumAux, 1000) + "
mil ";

dNumAux = dNumero % 1000;


sResultado += Numeros (dNumAux, 1);

//Enseguida verificamos si contiene punto, si es


as, los convertimos a texto.
sAux = dNumero.ToString();

if (sAux.IndexOf(".") >= 0)
sResultado += ObtenerDecimales (sAux);

//Las siguientes lneas convierten el primer


caracter a mayscula.
sAux = sResultado;
x = char.ToUpper (sResultado[1]);
sResultado = x.ToString ();

for (int i = 2; i<sAux.Length; i++)


sResultado += sAux[i].ToString();

return sResultado;
}

private string Numeros (double dNumAux, double dFactor) {


double dCociente = dNumAux / dFactor;
double dNumero = 0;
int iNumero = 0;
string sNumero = "";
string sTexto = "";

if (dCociente >= 100){


dNumero = dCociente / 100;

sNumero = dNumero.ToString();
iNumero = int.Parse
(sNumero[0].ToString());
sTexto

+=

this.sCentenas [iNumero] + " ";

dCociente = dCociente % 100;


if (dCociente >= 30){
dNumero = dCociente / 10;
sNumero = dNumero.ToString();
iNumero = int.Parse
(sNumero[0].ToString());
if (iNumero > 0)
sTexto

+= this.sDecenas [iNumero]

+ " ";

dNumero = dCociente % 10;


sNumero = dNumero.ToString();
iNumero = int.Parse
(sNumero[0].ToString());
if (iNumero > 0)
sTexto

+= "y " + this.sUnidades

[iNumero] + " ";


}

else {
dNumero = dCociente;
sNumero = dNumero.ToString();
if (sNumero.Length > 1)
if (sNumero[1] != '.')
iNumero = int.Parse
(sNumero[0].ToString() + sNumero[1].ToString());
else
iNumero = int.Parse
(sNumero[0].ToString());
else

iNumero = int.Parse
(sNumero[0].ToString());
sTexto

+= this.sUnidades[iNumero] + " ";

return sTexto;
}

private string ObtenerDecimales (string sNumero) {


string[] sNumPuntos;
string sTexto = "";
double dNumero = 0;

sNumPuntos = sNumero.Split('.');

dNumero = Convert.ToDouble(sNumPuntos[1]);
sTexto = "punto " + Numeros(dNumero,1);

return sTexto;
}
}
}

Anda mungkin juga menyukai