Las enumeraciones son un gran recurso que utilizo casi a diario en mis programas. De hecho, quizás las utilice en exceso, pero una vez me he acostumbrado a trabajar con ellas, lo cierto es que ya no puedo vivir sin ellas.
Un aspecto de las enumeraciones que no es muy utilizado pero que reporta grandes beneficios son las denominadas “enumeraciones binarias”. Por ejemplo, piensa que tenemos una enumeración “Persona” que tiene los siguientes valores: Alto, Bajo, Rubio, Moreno, Delgado, Gordo, Inteligente y Tonto. Todo el mundo sabe cómo asignar un valor sencillo de la enumeración a una variable, por ejemplo:
Public Enum Persona As Integer
Alto
Bajo
Rubio
Moreno
Delgado
Gordo
Inteligente
Tonto
End Enum
Sub Main()
Dim manolo As Persona = Persona.Alto
If manolo = Persona.Alto Then
Console.WriteLine("Manolo es alto")
End If
End Sub
Sin embargo ¿Cómo podemos guardar en la misma variable que Manolo, además de Alto también es Rubio y Delgado? Para resolver esto tenemos que utilizan enumeraciones binarias.
Definición
Una enumeración binaria tiene que cumplir las siguientes características:
· El primer valor de la enumeración tiene que ser 1 (no 0, como es por defecto).
· El resto de valores de la enumeración tienen que ser la potencia de 2.
· Tenemos que incluir el adorno Flags.
De este modo, la anterior enumeración quedaría como sigue:
<Flags()> _
Public Enum Persona As Integer
Alto = 1
Bajo = 2
Rubio = 4
Moreno = 8
Delgado = 32
Gordo = 64
End Enum
A partir de aquí tenemos que trabajar con operadores lógicos para asignar, consultar o retirar valores de una variable del tipo “Persona”. Los operadores disponibles son:
· And, conjunción lógica.
· Or, disyunción lógica.
· Not, negación lógica.
· Xor, exclusión lógica.
Agregar valores
Se agregan (suman) valores con el operador Or.
Dim manolo As Persona
manolo = Persona.Alto ' Manolo sólo es Alto (1)
manolo = Persona.Alto Or Persona.Rubio 'Manolo es Alto y Rubio. (5)
manolo = manolo Or Persona.Delgado 'Manolo es además de Alto y Rubio, también Delgado. (37)
Si nos fijamos, la primera asignación asigna el valor 1 (Alto) a la variable Manolo.
La segunda asignación asigna el valor 1 (Alto) y el valor 4 (Rubio) a la variable Manolo. De ese modo, Manolo vale 5 (la suma de Alto y Rubio).
Por último, la tercera asignación asigna el valor que ya tuviera Manolo (que podría ser cualquiera pero en nuestro caso es 4 – Alto y Rubio) más el valor 35 (Delgado). Finalmente, Manolo vale 37 (la suma de Alto y Rubio y Delgado).
En lo relativo a la suma de valores, da igual que sumemos varias veces un valor, no por ello Manolo será 2 veces alto!
Retirar valores
Se retiran (restan) valores con el operador Xor.
manolo = Persona.Alto Or Persona.Rubio
manolo = manolo Xor Persona.Rubio 'Manolo ya NO es Rubio (1)
Ahora, Manolo ya es no Rubio y su valor es 1, luego es Alto.
Con la resta de valores (Xor) hay que tener mucho cuidado, ya que si intenta restar un valor que actualmente no está asignado, en vez de restar lo que hará es sumar el valor. Por ejemplo:
manolo = Persona.Alto Or Persona.Rubio
manolo = manolo Xor Persona.Rubio 'Manolo ya NO es Rubio (1)
' Manolo no es Moreno, pero intentamos retirar (Xor) el valor Moreno, y en vez de retirarlo lo que hacemos es agregarlo
manolo = manolo Xor Persona.Moreno 'Ahora Manolo es Alto y Moreno (9)
Para resolver esto, antes de retirar (restar) un valor hay que asegurarse de que el valor existe realmente. Por ejemplo:
manolo = Persona.Alto Or Persona.Rubio
' Sólo si Manolo es Moreno, le retiramos (restamos) Manolo
If manolo And Persona.Rubio Then 'Comprobar si Manolo es Moreno
manolo = manolo Xor Persona.Moreno
End If
Consultar valores
Para consultar valores podemos llevar a cabo las siguientes instrucciones:
manolo = Persona.Bajo Or Persona.Moreno
If manolo = Persona.Bajo Then
Console.WriteLine("Manolo es SÓLO Bajo, nada más")
End If
If manolo And Persona.Bajo Then
Console.WriteLine("Manolo es Bajo")
End If
If manolo = (Persona.Bajo Or Persona.Moreno) Then
Console.WriteLine("Manolo es Bajo y Moreno")
End If
Un saludo!.
Me ha hecho acordar a los Flags del CommonDialog del viejo VB6, funcionan exactamente de la misma manera. Gracias por el post, ahora ya sé cómo implementar estos Flags :D
ResponderEliminar