23 de marzo de 2010

Enum C# Tips (Enumeraciones)

Las enumeraciones (enum) son tipos que agrupan un conjunto de constantes, veamos un ejemplo de enumeración.

Enum en C#, Ejemplo Básico

enum TipoDocumento
{
    DNI, // 0
    NIE, // 1
    Pasaporte, // 2
    Otro = 99
};

Nota: El tipo predeterminado subyacente de las enumeraciones es el int y el primer enumerador tiene valor 0, incrementándose sucesivamente en 1 (A menos que definamos otra cosa).

Veamos ahora como usar las enumeraciones, veamos un ejemplo de uso:

TipoDocumento var1 = TipoDocumento.DNI;
 
string strVar1 = var1.ToString();
 
TipoDocumento var2 = (TipoDocumento)2;
TipoDocumento var3 = (TipoDocumento)Enum.Parse(typeof(TipoDocumento), "NIE");
TipoDocumento var4 = (TipoDocumento)Enum.Parse(typeof(TipoDocumento), strVar1);
TipoDocumento var5 = (TipoDocumento)Enum.Parse(typeof(TipoDocumento), "2");
TipoDocumento var6 = (TipoDocumento)Enum.Parse(typeof(TipoDocumento), "99");
TipoDocumento var7 = (TipoDocumento)Enum.Parse(typeof(TipoDocumento), "Pasaporte");
TipoDocumento var8 = (TipoDocumento)Enum.Parse(typeof(TipoDocumento), "PASAPORTE");
//Esta última línea da un Error: Requested value 'PASAPORTE' was not found.

El resultado de estas variables sería el siguiente:

Enumeraciones

Nota: Un enumerador no puede contener espacio en blanco en su nombre.

 

Enum to List (Convertir Enumerador en Lista)

Muchas veces surge la necesidad de convertir un tipo de enumerador (enum) en una lista (Código, Descripción), por ejemplo para asociar dicha enumeración o enumerador a un combo box o lista desplegable, o cualquier otro control. Para ello podemos crearnos algún método extensor que nos facilite esta tarea.

Método Extensor (Enum to List)

El objetivo de nuestro ejemplo es poder hacer lo siguiente:

cmbTipoDocumentos.DataSource = typeof(TipoDocumento).ToCodigoDescripcion();
cmbTipoDocumentos.DataBind();

Donde 'ToCodigoDescripcion()' es un método extensor que nos devolverá una lista de cada elemento existente en el enumerador TipoDocumento, con la estructura (Código, Descripción) pero veamos la implementación del método extensor en cuestión:

public static List<CodigoDescripcion> ToCodigoDescripcion(this Type enumType)
{
  var arrValues = Enum.GetValues(enumType);
  var arrNames = Enum.GetNames(enumType);
 
  List<CodigoDescripcion> lstCodigos = arrNames.Select((name, index) =>
     new CodigoDescripcion
     {
       Codigo = arrValues.GetValue(index).GetHashCode().ToString(),
       Descripcion = name
     }).ToList();
 
  return lstCodigos;
}
 
public class CodigoDescripcion
{
  public string Codigo { get; set; }
  public string Descripcion { get; set; }
}
En este mismo método (ToCodigoDescripcion) estamos usando la clase (CodigoDescripcion) definida por nosotros; una posible variante pasaría por usar la estructura de .Net (KeyValuePair) que es muy similar a la creada por nosotros. De esta forma no tendríamos la necesidad de crear la clase, y el código quedaría de la siguiente manera:
 

public static List<KeyValuePair<string, string>> ToCodigoDescripcion(this Type enumType)

{

  var arrValues = Enum.GetValues(enumType);

  var arrNames = Enum.GetNames(enumType);

 

  List<KeyValuePair<string, string>> lstCodigos =

    arrNames.Select((name, index) => new KeyValuePair<string, string>(

      arrValues.GetValue(index).GetHashCode().ToString(), name)).ToList();

 

  return lstCodigos;

}

 

Nota:
Particularmente me gusta más esta segunda variante, pero queda a tu elección cuál de ellas aplicar. Además entiendo que la primera variante es mucho más fácil de leer.

 

Nota:
Posiblemente exista alguna otra forma más eficiente de implementar el método extensor anterior, si se te ocurre alguna no dudes en compartirla.

 

Artículos Relacionados:

1 comentario: