C# - Usando a classe TypeConverter


 Hoje veremos como usar a classe TypeConverter na linguagem C#.

Se você ainda não precisou criar o seu próprio conversor de tipo, isso um dia vai ter que acontecer, quer você desenvolva para web, desktop ou mobile.

Os conversores de tipo são usados para converter de um tipo para outro, por exemplo, um inteiro em uma string, e  a plataforma .NET vem com vários conversores de tipo que realizam todo o trabalho para você para os tipos .NET mais comuns.

Acontece que quando você cria seus próprios tipos complexos, precisa criar seus próprios conversores de tipo.

Neste artigo veremos como você pode escrever seu próprio conversor de tipo e, em seguida, atribuí-lo ao seu próprio tipo.

Os conversores de tipo são usados ​​principalmente para converter seu tipo em uma string ou uma string de volta ao seu tipo. Os conversores de tipo fornecem um desempenho melhor do que usar o recurso Reflection. Portanto, sempre que possível, evite a serialização binária que usa Reflection. Forneça seu próprio conversor de tipo.

A classe TypeConverter fornece uma maneira unificada de converter tipos de valores em outros tipos, bem como acessar valores padrão e subpropriedades.

Cada tipo que você declara pode ter um TypeConverter associado a ele usando o TypeConverterAttribute.

 Como os conversores funcionam

Os conversores de tipo permitem que você converta do seu tipo para outro tipo e também forma outro tipo de volta para o seu tipo. Todos os conversores de tipo são herdados da classe base TypeConverter.

Você precisa sobrescrever quatro métodos :

  1. CanConvertTo - Passa o tipo de destino necessário, por exemplo, tipo de string. O método retorna verdadeiro se puder ser convertido para esse tipo, caso contrário, será falso;
     
  2. ConvertTo - É passado junto com o tipo a ser convertido, o tipo de destino e as informações de cultura a serem usadas durante a conversão de tipo. Este método retorna o tipo convertido;
     
  3. CanConvertFrom - Retorna se esse conversor pode converter um objeto do tipo especificado no tipo desse conversor, usando o contexto especificado.
    O método retorna verdadeiro se puder converter daquele tipo de volta para o seu tipo. Caso contrário, retorna falso.
     
  4. ConvertFrom - Converte o objeto determinado para o tipo deste conversor, usando o contexto especificado e as informações da cultura. Este método retorna então o tipo convertido.

Os métodos CanConvertTo e ConvertTo são usados ​​ao converter do seu tipo para outro tipo, por exemplo, para uma string, e,  os métodos CanConvertFrom e ConvertFrom são usados ​​ao converter de outro tipo de volta para o seu tipo, por exemplo, de uma string.

A seguir temos as assinaturas destes métodos:

// para conversão de outro tipo para o tipo ao qual este conversor de tipo está associado
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType);
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value);

// para conversão deste tipo em algum outro tipo
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType);
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType);

Os métodos acima fornecem o núcleo de TypeConverters.

Um motivo para a confusão em torno dos TypeConverters é o fato de eles terem outras funções não relacionadas à função de conversão de tipo principal.

Criando um conversor de tipo

Vejamos um exemplo básico de uso da classe TypeConverter onde vamos converter um classe com uma propriedade Valor do tipo int para outra classe com a mesma propriedade Valor com tipo string.

Vamos criar um projeto Console (.NET Core) no VS 2019 Community e vamos definir duas classes Teste1 e Teste2 mostradas abaixo:

   public class Teste1
   {
        public Teste1(int valor)
        {
            Valor = valor;
        }
        public int Valor { get; set; }
    }

E :

    public class Teste2
    {
        public Teste2(string valor)
        {
            Valor = valor;
        }
        public string Valor { get; set; }
    }

E queremos converter o tipo Teste2 para Teste1. (string para int)

Para realizar esta conversão vamos criar um conversor usando os métodos da classe TypeConverter.

Para isso vamos criar a classe MeuConversorTeste que herda da classe TypeConverter e sobrescreve os métodos CanConvertFrom() e ConvertFrom() :

 public class MeuConversorTeste : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(Teste2))
                return true;
            else
                return base.CanConvertFrom(context, sourceType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            Teste2 teste2 = value as Teste2;

            // verifica se o objeto é do tipo Teste2
            if (teste2 == null)
                return base.ConvertFrom(context, culture, value);

            int n = System.Int32.Parse(teste2.Valor);
            Teste1 teste1 = new Teste1(n);
            return teste1;
        }
    }

A seguir precisamos decorar a classe Teste1 com o atributo TypeConverter():

[TypeConverter(typeof(MeuConversorTeste))]
public class Teste1
{
    public Teste1(int valor)
    {
       Valor = valor;
     }
     public int Valor { get; set; }
}

Agora no método Main() do arquivo Program vamos definir o código abaixo para fazer a conversão:

using System;
using System.ComponentModel;
namespace ConversorTipo
{
    class Program
    {
        static void Main(string[] args)
        {
              Teste1 teste1 = new Teste1(10);
              Teste2 teste2 = new Teste2("20");
              TypeConverter tc = TypeDescriptor.GetConverter(teste1);
              bool canConvert = tc.CanConvertFrom(null, typeof(Teste2));
              Console.WriteLine("Tecle algo para converter de Teste2 para Teste1...\n");
			Console.ReadKey();
           if (canConvert == true)
           {
	Teste1 teste1_teste2 = tc.ConvertFrom(teste2) as Teste1;
    	if (teste1_teste2 != null)
	{
   	  Console.WriteLine("Conversão de Teste2 para Teste1 feita com sucesso\n");
	  Console.WriteLine(teste1_teste2.Valor.ToString());
                 }
            }
            else
            {
                Console.WriteLine("Não é possível converter Teste2 para Teste1");
            }
       }
    }
}

Executando o código temos o seguinte resultado:

Pegue o código do projeto aqui :  ConversorTipo.zip

"Se alguém não estiver em mim, será lançado fora, como a vara, e secará; e os colhem e lançam no fogo, e ardem. Se vós estiverdes em mim, e as minhas palavras estiverem em vós, pedireis tudo o que quiserdes, e vos será feito."
João 15:6,7

Referências:


José Carlos Macoratti