1

Enumerator em C#: Adicionando um CustomAttribute

#.NET C#
Sandro Vieira
Sandro Vieira

Enumeradores são muito úteis e elegantes. Quando usados em laços de repetição, tomadas de decisão e até mesmo como parâmetros em métodos eles tornam o código mais fácil de entender. Porém existe um inconveniente quando podemos utilizá-los em saídas para o usuário, seja em um dropbox, checkbox ou até mesmo em uma aplicação console.


No Bootcamp MRV .NET Developer, o primeiro projeto para consolidar o aprendizado de como pensar orientado a objetos, como modelar o domínio da aplicação e como utilizar recursos de coleção propõe uma aplicação para Séries e Filmes. 


Vamos utilizar um Enumerator para Gêneros, para fins de exemplo, vamos adotar a estrutura abaixo:


    public enum EGeneros
    {
        Acao,
        Aventura,
        Comedia,
        Drama,
        Fantasia,
        Ficcao_Cientifica,
        Policial,
        Romance,
        Suspense,
        Terror
    }


Quando nos deparamos com as funcionalidades para Adicionar ou Alterar um título, listamos esses gêneros para o usuário, ilustrado abaixo:



Os gêneros de Ação, Comédia e Ficção Científica não ficam amigáveis. Podemos implementar um método com IF ou SWITCH..CASE para retornar uma descrição mais personalizada, porém gostaria de apresentar outra maneira utilizando o CustomAttributes do System.ComponentModel e Reflection.


Mais informações sobre Reflection podem ser encontradas aqui: https://docs.microsoft.com/pt-br/dotnet/framework/reflection-and-codedom/reflection


Implementando nossa classe Helper


using System;
using System.ComponentModel;
using System.Reflection;

namespace DIO.Series
{
    public static class EnumHelper
    {
        /// <summary>
        /// Retorna a descrição do Enumerator
        /// </summary>
        /// <param name="e">Enumerator</param>
        /// <returns>Retorna a descrição customizada do Enumerator quando informado, caso contrátrio retorna o nome informado</returns>
        /// <example>
        ///     string desc = EnumHelper.GetEnumDescription(EGenero.Ficcao_Cientifica);
        ///     desc recebe: "Ficção Científica"
        /// </example>
        public static string GetDescription(Enum e)
        {
            //Descobre os atributos de um campo e fornece acesso aos metadados do campo.
            FieldInfo info = e.GetType().GetField(Enum.GetName(e.GetType(), e));


            //Especifíca uma descrição para uma propriedade ou evento
            DescriptionAttribute[] enumAttributes = (DescriptionAttribute[])info.GetCustomAttributes(typeof(DescriptionAttribute), false);
 
            //Encontra o atributo customizado e retorna a descrição.
            if (enumAttributes.Length > 0)
                return enumAttributes[0].Description;


            //Caso contrário, retorna o nome definido no emumerator
            return e.ToString();
        }
    }
}


Dessa forma podemos atualizar nosso Enumerator, adicionando o nosso Custom Attribute [Description("")] com uma descrição personalizada, quando necessário:


using System.ComponentModel;

namespace DIO.Series
{
    public enum EGeneros
    {
        [Description("Ação")]
        Acao,
        Aventura,
        [Description("Comédia")]
        Comedia,
        Drama,
        Fantasia,
        [Description("Ficção Científica")]
        Ficcao_Cientifica,
        Policial,
        Romance,
        Suspense,
        Terror
    }
}


Podemos agora fazer uma chamada ao EnumHelper.GetDescription() de dentro da nossa rotina, como por exemplo, implementando um método chamado ExibirGeneros():


        /// <summary>
        /// Retorna a lista de gêneros do enumerator
        /// </summary>
        /// <returns><see cref="System.String">string</see> com a lista de gêneros</returns>
        static string ExibirGeneros()
        {
            StringBuilder generos = new StringBuilder("Generos: ");
            foreach(int i in Enum.GetValues(typeof(EGeneros)))
            {
                generos.Append($"{i}: {EnumHelper.GetDescription((EGeneros)i)}\t");
            }
            
            return generos.ToString();
        }


Console.WriteLine(ExibirGeneros());


Agora conseguimos exibir para o usuário uma descrição mais personalizada:



Espero que tenham gostado dessa implementação e que seja útil nos projetos de vocês!

Caso tenha uma sugestão ou crítica, por favor deixe seu comentário que ficarei feliz em saber o que você tem a dizer.


Abraço!

0
16

Comentários (1)

0
Jose Neto

Jose Neto

27/03/2021 16:14

Legal seu artigo Sandro. O enum é de fato elegante!


Existe outra forma também com Dictionary, porém não tão elegante.


 public enum TipoPessoa

    {

      Física = 1,

      Juridica = 2       

    }    


var dictionary = new Dictionary<int, string>

      {

        {(int)TipoPessoa.Física, "Pessoa Física"},

        {(int)TipoPessoa.Juridica, "Pessoa Jurídica"}

      };

None

Brasil