Enumeraciones en Visual Basic. Uso, declaración y sintaxis de un enumeration

Las enumeraciones no son una novedad de Visual Basic 2010, aunque como veremos, si lo es la forma de usarlas, e incluso de declararlas. Aunque esos cambios son menores y la funcionalidad que teníamos en VB6 sigue siendo la misma.

De todas formas echemos un breve repaso a las enumeraciones para que tengamos los conceptos claros.

Una enumeración es una serie de constantes que están relacionadas entre sí. La utilidad de las enumeraciones es más manifiesta cuando queremos manejar una serie de valores constantes con nombre, es decir, podemos indicar un valor, pero en lugar de usar un literal numérico, usamos un nombre, ese nombre es, al fin y al cabo, una constante que tiene un valor numérico.

En Visual Basic 2010 las enumeraciones pueden ser de cualquier tipo numérico integral, incluso enteros sin signo, aunque el valor predefinido es el tipo Integer.

Podemos declarar una enumeración de varias formas:

El nombre de los miembros de las enumeraciones

Tanto si indicamos o no el atributo Flags a una enumeración, la podemos usar de esta forma:

	
Dim c As Colores = Colores.Azul Or Colores.Rojo
	

Es decir, podemos "sumar" los valores definidos en la enumeración. Antes de explicar con detalle que beneficios nos puede traer el uso de este atributo, veamos una característica de las enumeraciones que no teníamos en VB6.

Como hemos comentado, las enumeraciones son constantes con nombres, pero en Visual Basic 2010 esta definición llega más lejos que en VB6, de hecho, podemos saber "el nombre" de un valor de una enumeración, para ello tendremos que usar el método ToString, (el cual se usa para convertir en una cadena cualquier valor numérico).

Por ejemplo, si tenemos la siguiente asignación:

	
Dim s As String = Colores.Azul.ToString
	

La variable s contendrá la palabra "Azul" no el valor 4 que le habíamos asignado antes a "Azul" en al enumeración.

Esto es aplicable a cualquier tipo de enumeración, se haya o no usado el atributo FlagsAttribute.

Una vez aclarado este comportamiento de las enumeraciones en Visual Basic 2010, veamos que es lo que ocurre cuando sumamos valores de enumeraciones a las que hemos aplicado el atributo Flags y a las que no se lo hemos aplicado. Empecemos por este último caso.

Si tenemos este código:

	
Enum Colores As Byte
    Rojo = 1
    Verde = 2
    Azul = 4
End Enum

Dim c As Colores = Colores.Azul Or Colores.Rojo

Dim s As String = c.ToString
	

El contenido de la variable s será "5", es decir, la representación numérica del valor contenido: 4 + 1, ya que el valor de la constante Azul es 4 y el de la constante Rojo es 1.

Pero si ese mismo código lo usamos de esta forma (aplicando el atributo Flags a la enumeración):

	
<Flags()>; _
Enum Colores As Byte
    Rojo = 1
    Verde = 2
    Azul = 4
End Enum

Dim c As Colores = Colores.Azul Or Colores.Rojo

Dim s As String = c.ToString
	

El contenido de la variable s será: "Rojo, Azul", es decir, se asignan los nombres de los miembros de la enumeración que intervienen en ese valor, no el valor "interno".

Los valores de una enumeración no son simples números

Como hemos comentado, los miembros de las enumeraciones realmente son valores de un tipo de datos entero (en cualquiera de sus variedades) tal como podemos comprobar en la figura:

Los tipos subyacentes posibles de una enumeración

Por tanto, podemos pensar que al igual que ocurría en VB6, podemos usar cualquier valor para asignar a una variable declarada como una enumeración, al menos si ese valor está dentro del rango adecuado.

Pero en Visual Basic 2010 esto no es posible, al menos si lo hacemos de forma "directa" y con Option Strict conectado, ya que recibiremos un error indicándonos que no podemos convertir, por ejemplo, un valor entero en un valor del tipo de la enumeración. En la figura de abajo podemos ver ese error al intentar asignar el valor 3 a una variable del tipo Colores (definida con el tipo predeterminado Integer).

Error al asignar un valor normal a una variable del tipo Colores

El error nos indica que no podemos realizar esa asignación, pero el entorno integrado de Visual Basic 2010 Express también nos ofrece alternativas para que ese error no se produzca, esa ayuda se obtiene pulsando en el signo de admiración que tenemos justo donde está el cursor del ratón, pero no solo nos dice cómo corregirlo, sino que también nos da la posibilidad de que el propio IDE se encargue de corregirlo, tal como podemos apreciar en esta otra figura.

Figura 1.9. Opciones de corrección de errores

Lo único que tendríamos que hacer es pulsar en la sugerencia de corrección, que en este caso es la única que hay, pero en otros casos pueden ser varias las opciones y tendríamos que elegir la que creamos adecuada.

El código final (una vez corregido) quedaría de la siguiente forma:

	
Dim c As Colores = CType(3, Colores)
	

CType es una de las formas que nos ofrece Visual Basic 2010 de hacer conversiones entre diferentes tipos de datos, en este caso convertimos un valor entero en uno del tipo Colores.

Si compilamos y ejecutamos la aplicación, ésta funcionará correctamente.

Aunque sabemos que es posible que usando CType no asignemos un valor dentro del rango permitido. En este caso, el valor 3 podríamos darlo por bueno, ya que es la suma de 1 y 2 (Rojo y Verde), pero ¿que pasaría si el valor asignado es, por ejemplo, 15? En teoría no deberíamos permitirlo.

Estas validaciones podemos hacerlas de dos formas:

En el siguiente ejemplo podemos hacer esa comprobación.

	
Sub mostrarColor(ByVal c As Colores)
    ′ comprobar si el valor indicado es correcto
    ′ si no está¡ definido, usar el valor Azul
    If [Enum].IsDefined(GetType(Colores), c) = False Then
        c = Colores.Azul
    End If"
    Console.WriteLine("El color es {0}", c)
End Sub
	

Este código lo que hace es comprobar si el tipo de datos Colores tiene definido el valor contenido en la variable c, en caso de que no sea así, usamos un valor predeterminado.

Nota: La función IsDefined sólo comprueba los valores que se han definido en la enumeración, no las posibles combinaciones que podemos conseguir sumando cada uno de sus miembros, incluso aunque hayamos usado el atributo FlagsAttribute.

Muy bien ahora sí hemos terminado esta sección. No olvides dejar tus comentarios.

La última actualización de este artículo fue hace 1 año