No mundo da programação vivemos constantemente alterando os tipos de dados para atender necessidades técnicas. Hora convertemos uma data digitada (texto) para seu tipo nativo DateTime, hora convertemos um valor de horas para o seu tipo correspondente, o TimeSpan.

Existem na teoria as conversões implícitas e explicitas, porém existem também as conversões realizadas pelos desenvolvedores, as User-Defined conversions e as conversões com auxílio de classes que proveem conversão de tipos não compatíveis entre si.

Vamos focar apenas nos dois primeiros tipos, por serem os de uso mais comum para todos.

Conversão Implícita

O nome já diz: implícito. Ao declarar esse tipo de conversão, o compilador identifica que ambos são de tipos compatíveis, sendo assim nenhuma intervenção na hora do build é feita e há a garantia que nenhuma informação seja perdida durante a conversão.

A conversão implícita não só vale para as variáveis TypeValue. Objetos que são ReferenceType, são capazes de uma conversão implícita quando são de uma classe derivada ou até mesmo uma interface. Exemplificamos cada caso nas Listagens 1 e 2.


using System;
namespace ConversionTypeSafe
{
    class Program
    {
        static void Main(string[] args)
        {
            sbyte a = 10;
            short b = a;
            int c = b;
            long d = c;
            float e = d;
            double f = e;

           Console.Write(f);           
           Console.Read();
        }
    }
}
Listagem 1. Conversão Implícita de ValueType

namespace ConversionImplicitReferenceType
{
    class Humano
    {
        //Propriedades e Métodos
    }
    class Feminino : Humano
    {
        //Propriedades e Métodos
    }
    class Masculino : Humano
    {
        //Propriedades e Métodos
    }

    class Program
    {
        static void Main(string[] args)
        {
            Masculino Robson = new Masculino();
            Humano humano = Robson;
        }
    }
}
Listagem 2. Conversão Implícita de ReferenceType (DerivedClass)

A Tabela 1 mostra a conversão implícita disponibilizada pela Microsoft, que contém todas as formas implícitas possíveis. Vale ressaltar que esse tipo de conversão deve ser feita de forma cuidadosa, pois a tipos como Int que possuem menos pontos de precisão nos valores armazenados, o que pode acarretar em arredondamentos de valores de forma errônea.

DePara
sbyteshort , int, long, float, double, ou decimal
byteshort , ushort, int, uint, long, ulong, float, double, ou decimal
shortint , long, float, double, ou decimal
ushortint , uint, long, ulong, float, double, ou decimal
intlong , float, double, ou decimal
uintlong , ulong, float, double, ou decimal
longfloat , double, ou decimal
Tabela 1. Conversão implícita

Tendo conhecimento da tabela, veja que ao tentar uma conversão implícita, por exemplo, do tipo ulong para int, o que ocorre é que o interpretador informa que não é possível converter o tipo int para ulong.

Conversão implícita de char para int

Ao fazer a conversão implícita de um valor do tipo char para um valor do tipo int retornamos um valor que corresponde ao código ASCII do valor do tipo char, conforme a Listagem 3.


int codigo = 'X'; // conversão implícita do valor do tipo char "X" 
// para o tipo inteiro que corresponde a seu código ASCII
Console.WriteLine(codigo);
 // será exibido o valor 88, codigo ASCII para o caractere "X"
Listagem 3. Conversão implícita de tipo char para int

Conversão implícita de inteiros em expressões

Quando temos uma expressão com uma divisão entre dois números inteiros o resultado será outro número inteiro, conforme a Listagem 4.


var x = 15 / 2; // o resultado desta divisão entre os números inteiro 15 e 2
// será o número inteiro 7
Listagem 4. Divisão entre números inteiros
Mas se nessa expressão um dos números fosse de ponto flutuante, o outro número inteiro seria convertido implicitamente para um número de ponto flutuante. E o resultado da expressão também seria um número de ponto flutuante e não um inteiro, conforme a Listagem 5.

var x = 15 / 2.0; // o número ineiro 15 é convertido implicitamente 
//para o mesmo tipo double do número 2.0
// e o valor de x é 7.5 do tipo double
Listagem 5. Conversão implícita de um número inteiro
Se o tipo de ponto flutuante for double o resultado da expressão será double e se não houver um tipo double o resultado será float. Essa conversão implícita resulta em valores mais precisos.

Conversão implícita com var

Quando utilizamos a palavra var ao declarar uma variável conforme a Listagem 6 fazemos uma conversão implícita em que o compilador determina o tipo de dado de acordo com o valor atribuído a variável.


var x = 5; // x é convertido implicitamente para o tipo int 
var y = 5.0; // y  é convertido implicitamente para o tipo double
Listagem 6. Conversão implícita com var

Conversão Explicita

Essa conversão deixa o código mais legível. A forma de se declarar uma conversão desse tipo facilita no entendimento da necessidade.

Para realizar este tipo, você deve declarar à frente da variável da direita e entre parênteses o tipo de dado que deseja.

Facilitando, seguem os exemplos nas Listagens 7 e 8.


using System;
namespace ConversionExplicit
{
    class Program
    {
        static void Main(string[] args)
        {
            sbyte a = 10;
            short b = (short)a;
            int c = (int)b;
            long d = (long)c;
            float e = (long)d;
            double f = (float)e;
            Console.Write(f);
            Console.Read();
        }
    }
}
Listagem 7. Conversão Explicita de TypeValue

namespace ConversionExplicitRefenceType
{
    class Humano
    {
        //Propriedades e Métodos
    }
    class Feminino : Humano
    {
        //Propriedades e Métodos
    }
    class Masculino : Humano
    {
        //Propriedades e Métodos
    }
    class Program
    {
        static void Main(string[] args)
        {
            Feminino Mulher = new Feminino();
            Humano SerHumano = Mulher;
            Feminino OutraMulher = (Feminino)SerHumano;
        }
    }
}
Listagem 8. Conversão Explicita de ReferenceType

Existe também uma tabela de equivalências para o tipo explicito, conforme a Tabela 2.

DePara
sbytebyte , ushort, uint, ulong, ou char
byteSbyte ou char
shortsbyte , byte, ushort, uint, ulong, ou char
ushortsbyte , byte, short, ou char
intsbyte , byte, short, ushort, uint, ulong, ou char
uintsbyte , byte, short, ushort, int, ou char
longsbyte , byte, short, ushort, int, uint, ulong, ou char
Tabela 2. Equivalências para o tipo explicito

Existe uma variante da conversão explicita que utiliza a palavra chave as. Ele realiza apenas conversões de referências compatíveis ou tipos null. Quando uma conversão desse tipo não é possível, ele retorna null para o objeto.

Veja um exemplo na Listagem 9.


namespace ConversionExplicitRefenceType
{
    class Humano
    {
        //Propriedades e Métodos
    }
    class Feminino : Humano
    {
        //Propriedades e Métodos
    }
    class Masculino : Humano
    {
        //Propriedades e Métodos
    }
    class Program
    {
        static void Main(string[] args)
        {
            Feminino Mulher = new Feminino();
            Humano SerHumano = Mulher;
            Feminino OutraMulher = SerHumano as Feminino;
        }
    }
}
Listagem 9. Conversão Explicita com as

Caso o objeto SerHumano seja null ou não seja do tipo Feminino, o as retorna o valor null para o objeto da esquerda.

Conclusão

Os tipos de conversão passados aqui são ações que com o tempo se tornam naturais, mas são primordiais para boas práticas.

Não deixem de pesquisar mais sobre os pontos flutuantes de cada tipo de dado, principalmente quando forem trabalhar com maior precisão nos valores decimais.

Assista aos cursos de .NET da DevMedia.

Referências