Parse, Convert ou TryParse ?!

Você já deve ter notado que quando queremos efetuar uma conversão de valores para distintos tipos, o C# (assim também como VB.NET) possui diversos métodos com sobrecargas que atendem perfeitamente as necessidades de um desenvolvedor, mas você já se perguntou se esta conversão sendo feita da maneira correta ? você esta preparando seu código para futuras exceções que esta conversão pode disparar ? 

Com estas duas perguntas acima, podemos dar inicio a uma breve analise de como e qual tipo de conversão devemos adotar. Antes de mais nada, devemos deixar bem claro que o C# é uma linguagem tipada, para termos um bom inicio que tal analisarmos de fato o funcionamento de algumas das alternativas que pretendemos estudar. Usando do utilitário gratuito dotPeek, que nada mais é do que um descompilador, com ele podemos abrir os assembly da Microsoft e estudar estas implementações, vejamos:

Int32.Parse()
convert-parse-tryparse-1

Convert.ToInt32()
convert-parse-tryparse-2

Interessante né, repare que quando utilizamos do método Parse, não existe uma verificação quanto ao valor que foi passado, se o mesmo é nulo ou não, logo se tentarmos efetuar uma conversão cujo o valor a ser convertido é nulo, uma exceção de ArgumentNullException será disparada, para exemplificar, vejamos estas tentativas de conversão usando do método Parse:

string valor1 = "abc";
string valor2 = "12345678901";
string valor3 = null;
string valor4 = "10";

Int32.Parse(valor1); // FormatException
Int32.Parse(valor2); // OverflowException
Int32.Parse(valor3); // ArgumentException
Int32.Parse(valor4); // 10

Se sabemos que o método Parse esta sujeito a este tipo de exceção, porque devemos utiliza-lo ? A resposta parece meio obvia, se existe alguma maneira de você assegurar que o valor a ser convertido nunca será nulo, use e abuse deste método de conversão. O mesmo cenário podemos utilizar para o método Convert, ao passarmos um valor nulo para ser convertido, existe uma verificação como pode ser visto na foto postada anteriormente, mostrando que quando o valor que esta prestes a ser convertido for nulo, a conversão de fato não é realizada, pois o método se encarregara de nos retornar o valor padrão de acordo com a conversão solicitada, vejamos:

string valor1 = "abc";
string valor2 = "12345678901";
string valor3 = null;
string valor4 = "10";

Convert.ToInt32(valor1); // FormatException
Convert.ToInt32(valor2); // OverflowException
Convert.ToInt32(valor3); // 0 
Convert.ToInt32(valor4); // 10

Ok, ok, acho que as duas opções de conversões acima atendem perfeitamente qualquer desenvolvedor, mesmo assim elas estão sujeitas a exceções, tais como FormatException que é disparada quando tentamos converter letras em números, por exemplo. Também temos a  exceção OverflowException que é disparada quando tentamos converter um valor maior que o valor máximo suportado pelo Int32 ou um valor menor que o seu valor mínimo também suportado pelo Int32. É ai que entra a terceira opção de conversão, o TryParse, podemos utiliza-lo junto a uma estrutura de decisão, vulgo “if” e não podemos nos esquecer da variável de saída, que vai ser responsável por armazenar o resultado desta conversão, vejamos:

string valor1 = "abc";
string valor2 = "12345678901";
string valor3 = null;
string valor4 = "10";

int resultado;

if (Int32.TryParse(valor1, out resultado)) // Retorno 'False', valor da variável 'resultado' é igual a 0
{ /* Seu código */ }

if (Int32.TryParse(valor2, out resultado)) // Retorno 'False', valor da variável 'resultado' é igual a 0
{ /* Seu código */ }

if (Int32.TryParse(valor3, out resultado)) // Retorno 'False', valor da variável 'resultado' é igual a 0
{ /* Seu código */ }

if (Int32.TryParse(valor4, out resultado)) // Retorno 'True', valor da variável 'resultado' é igual a 10
{ /* Seu código */ }

Ufa, creio que com este trio, qualquer desenvolvedor conseguira efetuar uma conversão, podendo trabalhar com opções onde exceções são disparadas ou não.

Apenas um conselho quanto ao tratamento de exceções, se sabemos quais exceções podem ser disparadas, nada mais justo do que cuidarmos delas com carinho, se você ganha por linha de código escrita, melhor ainda, pois poderá justificar esta implementação :D

string valor1 = "10";

try
{
    Int32.Parse(valor1);
}
catch (FormatException ex)
{ 
    /* Devido tratamento aqui */ 
}
catch (OverflowException ex)
{
    /* Devido tratamento aqui */ 
}
catch (ArgumentException ex)
{ 
    /* Devido tratamento aqui */
}

Bom pessoal, espero que tenham gostado, Até.

Opine, discuta, participe ou simplesmente deixe um comentário