[TIP] Obtener Nombres o Descripciones de un Enumerado (Avanzado)

Después de haber publicado Obtener Nombres de un Enumerado, Pablo Nuñez(@pablonete), me ha lanzado una pregunta:

"¿Has probado [Description("x")] en los enum?”

 

¿Qué es Description?

Es un atributo que nos permite dar una descripción a un miembro del código.

 

Bien dejando de lado la definición, el enunciado sería:

Mostrar la Descripción de los miembros de la enumeración, si existen.

Para poder lograrlo, he tenido que recurrir al NameSpace System.Reflection gracias al cual he visto como obtener todas los datos que requeria.

Para comenzar el ejemplo he creado un pequeño modulo:

C#

   1: using System.ComponentModel;

   2:         enum miEnum

   3:         {

   4:             [Description("Elemento 1")]

   5:             valor1,

   6:             [Description("Elemento 2")]

   7:             valor2,

   8:             valor3

   9:         }

VB

   1: Imports System.ComponentModel

   2: Public Enum MiEnum

   3:     <Description("Elemento 1")> _

   4:      Valor1

   5:     <Description("Elemento 2")> _

   6:     Valor2

   7:     Valor3

   8: End Enum

He creado una función que es la que va obtener dicho atributo, y en caso de que no exista devolverá el valor del Nombre (como en el post anterior).

 

C#

   1: private Dictionary<int,string> GetListDesc(Type tipoEnum)

   2: {

   3: Dictionary<int,string> lValores=new Dictionary<int,string>();

   4:     string key="";

   5:     int valorNum=0;

   6:     foreach (var valor in Enum.GetValues(tipoEnum))

   7:     {

   8:        var query=valor.GetType().

   9:            GetField(valor.ToString()).GetCustomAttributes(true).

  10:            Where(a=> a.GetType().Equals(typeof(System.ComponentModel.DescriptionAttribute)));

  11:         valorNum=Convert.ToInt32(valor);

  12:         if (query.Any())

  13:         {

  14:             key=(valor.GetType().

  15:                 GetField(valor.ToString()).GetCustomAttributes(true).

  16:                 Where(a=> a.GetType().Equals(typeof(System.ComponentModel.DescriptionAttribute))).

  17:                 FirstOrDefault() as System.ComponentModel.DescriptionAttribute).Description;                }

  18:         else

  19:         {

  20:             key = Enum.GetName(tipoEnum, valor);

  21:         }

  22:         lValores.Add(valorNum,key);

  23:     }

  24:     return lValores;

  25: }

VB

 

   1: Private Function GetListDesc(ByVal tipoEnum As Type) As Dictionary(Of Integer, String)

   2:  

   3:     Dim lValores As New Dictionary(Of Integer, String)

   4:  

   5:     For Each valor In [Enum].GetValues(tipoEnum)

   6:         If valor.GetType().GetField(valor.ToString()).

   7:             GetCustomAttributes(True).

   8:             Where(Function(a) a.GetType().

   9:                       Equals(GetType(System.ComponentModel.DescriptionAttribute))).Any() Then

  10:             lValores.Add(valor, valor.GetType().

  11:                          GetField(valor.ToString()).

  12:                          GetCustomAttributes(True).

  13:                          Where(Function(a) a.GetType().

  14:                                    Equals(GetType(System.ComponentModel.DescriptionAttribute))).

  15:                                FirstOrDefault().Description)

  16:         Else

  17:             lValores.Add(valor, [Enum].GetName(tipoEnum, valor))

  18:         End If

  19:     Next

  20:  

  21:     Return lValores

  22: End Function

 

Y para invocarlas:

C#

   1: Dictionary<int, string> miEnum = new Dictionary<int, string>();

   2:  

   3:             var query = (from int n in Enum.GetValues(typeof(System.Windows.Forms.DialogResult))

   4:                         select new {

   5:                             n,

   6:                             Valor = GetListDesc(typeof(miEnum)).FirstOrDefault(a => a.Key == n).Value

   7:                             

   8:                         });

   9:  

  10:             comboBox1.DataSource = query.ToList();

  11:             comboBox1.DisplayMember = "Valor";

  12:             comboBox1.ValueMember = "n";

VB

 

   1: Dim query = From n As Integer In [Enum].GetValues(GetType(MiEnum))

   2:             Select New With {n, .Valor = GetListDesc(GetType(MiEnum)).

   3:             Where(Function(a) a.Key = n).FirstOrDefault().Value}

   4:  

   5: ComboBox1.DataSource = query.ToList()

   6: ComboBox1.DisplayMember = "Valor"

 

Espero que os sea de utilidad y si tenéis dudas aquí estoy.

Saludos.

6 comentarios en “[TIP] Obtener Nombres o Descripciones de un Enumerado (Avanzado)”

  1. Pues si, interesante ver como uno puede mezclar elementos de “Diseño Visual y Tooling” como description con el objetivo de un desarrollo por medio del DescriptionAttribute. ¿Digo, yo, lo siguiente será poner los labels con los summary del código… en fin

  2. Pedro, te pongo un ejemplo:

    imaginate que tienes una enumeración con valores como I1, IL, ILP, CMP…

    Para el desarrollador pueden tener un valor perfectamente válido, pero probablemente de cara al usuario no tengan ningun sentido.¿en este caso sigues pensando “En fin”?

  3. Hombre, pues claro que sigo pensando en fin, eso son etiquetas de UI y por lo tanto tendría que ser elementos incrustados en recursos, los tendrás que localizar, adaptar, cambiar facilmente etc….a ver, que DescriptionAttribute es un attributo de TOOLING ( con esto no te parece suficiente),

  4. ¿Has usado alguna vez BD de terceros con nombres de tablas, campos … no entendibles? Imagino que sí. ¿A que con total seguridad, te has encontrado en dicha Base de Datos, vistas con nombres mas amigables?

    Esta situación no es la misma, pero es una forma de hacerte entender, o al menos eso creo yo.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *