Dica: Utilizando descrições com Enums no C#

Facebooktwittergoogle_plusredditpinterestlinkedinmail

Hoje vamos ver uma dica rápida, para trabalharmos com descrições em um Enum no .net, vendo como obter a descrição a partir do Enum, e também como obter o valor do Enum a partir da descrição. Então vamos criar uma Class Library (.NET Core) no Visual Studio 2017, e dar o nome de DemoEnum.Core.

Nós vamos precisar instalar um pacote em nosso projeto, para isso abra o console do Nuget e digite:

Install-Package System.ComponentModel.Primitives

Esse pacote contém o atributo DescriptionAttribute, que nós vamos utilizar. Após a instalação do pacote, crie uma classe com o nome EnumExtender e defina-a como estática, pois nós vamos fazer um Extender para Enums. Agora crie o método abaixo:

public static string GetDescription(this Enum enumerationValue)
{
	Type type = enumerationValue.GetType();
	MemberInfo member = type.GetMembers().Where(w => w.Name == Enum.GetName(type, enumerationValue)).FirstOrDefault();
	var attribute = member?.GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault() as DescriptionAttribute;
	return attribute?.Description != null ? attribute.Description : enumerationValue.ToString();
}

O que fizemos aqui, foi criar um método de extensão para um Enum, que retornará sua descrição.

Agora vamos criar o método que a partir da descrição nos devolve o valor do Enum, para isso crie o método abaixo:

public static T GetEnumValue<T>(this string description)
{
	var type = typeof(T);
	if (!type.GetTypeInfo().IsEnum)
		throw new ArgumentException();
	
	var field = type.GetFields().SelectMany(f => f.GetCustomAttributes(typeof(DescriptionAttribute), false), (f, a) => new { Field = f, Att = a })
								.Where(a => ((DescriptionAttribute)a.Att).Description == description).SingleOrDefault();
	return field == null ? default(T) : (T)field.Field.GetRawConstantValue();
}

Agora vamos criar um Enum para testarmos nossos métodos, então crie um Enum com o nome ClasseJedi com o código abaixo:

using System.ComponentModel;

namespace DemoEnum.Core
{
    public enum ClasseJedi
    {
        [Description("Cavaleiro Jedi")]
        CavaleiroJedi,
        [Description("Mestre Jedi")]
        MestreJedi
    };
}

Agora, vamos criar um projeto de teste unitário com o nome DemoEnum.Test, escoha a opção Unit Test Project (.NET Core). No projeto de teste crie uma classe de teste com o nome UnitTestEnumExtender com o conteúdo abaixo:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using DemoEnum.Core;

namespace DemoEnum.Test
{
    [TestClass]
    public class UnitTestEnumExtender
    {
        [TestMethod]
        public void TestGetDescription()
        {
            Assert.AreEqual("Cavaleiro Jedi", ClasseJedi.CavaleiroJedi.GetDescription());
        }

        [TestMethod]
        public void TestGetEnumValue()
        {
            Assert.AreEqual(ClasseJedi.CavaleiroJedi, "Cavaleiro Jedi".GetEnumValue<ClasseJedi>());
        }
    }
}

O que fizemos no método TestGetDescription foi pegar a descrição de CavaleiroJedi e compará-la com o valor “Cavaleiro Jedi”, e no método TestGetEnumValue fizemos o contrário, a partir da descrição “Cavaleiro Jedi” nós obtivemos o valor do enum CavaleiroJedi. Rode o teste e veja os testes passarem.

Com uma pequena classe, podemos trabalhar com descrições em enums de forma simples e prática. Coloquei o código-fonte completo do nosso exemplo no GitHub: https://github.com/desenvolvedorninja/enum-com-descricao

E também publiquei apenas os métodos de conversão no Gist: https://gist.github.com/rdakar

Quase 20 anos de experiência no mercado de TI.
Atuação em grandes empresas como Netshoes, Borland, JBS, Bradesco, Hospital das Clínicas, Rede, Prodam, HSPE, Instituto Ayrton Senna, e também em empresas internacionais como Delta Dental, T-Mobile, Pepsi e Mckesson.
Fundador da TecPrime Solutions, administrador da comunidade nopCommerce Brasil, e autor dos sites InvestFacil.net e Desenvolvedores.ninja

Facebooktwittergoogle_plusredditpinterestlinkedinmail

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *