A aula anterior terminou com um problema bem formulado: o usuário digita "30", mas o programa recebe o texto "30", e não o número 30 — e texto não serve para cálculos. Esta aula resolve esse problema e, ao fazê-lo, ensina uma das lições mais importantes de toda a programação: a de que os dados que vêm do mundo exterior não são confiáveis, e um bom programa se prepara para isso. Aprenderemos a converter texto em número de duas maneiras — uma ingênua, que funciona quando tudo dá certo mas quebra o programa quando algo dá errado, e uma robusta, que lida com o inesperado de forma elegante. Ao final, seus programas interativos deixarão de ser frágeis e passarão a resistir a entradas malucas.
Conversão: mudando a natureza de um valor
Converter um valor significa transformá-lo de um tipo em outro — no nosso caso, de string (texto) para int (número inteiro). A conversão não muda o valor no sentido do seu significado; muda a sua natureza, de modo que ele passe a poder ser usado onde aquela natureza é exigida. O texto "30" e o número 30 representam a mesma quantidade aos nossos olhos, mas são coisas diferentes para o computador; a conversão constrói a ponte entre eles.
O C# oferece, para cada tipo numérico, uma ferramenta de conversão a partir de texto. Para o int, a forma mais direta chama-se int.Parse (a palavra inglesa parse significa, aproximadamente, "analisar e interpretar"). Ela recebe um texto e devolve o número correspondente:
string textoIdade = "30";
int idade = int.Parse(textoIdade); // converte o texto "30" no número 30
Console.WriteLine(idade + 1); // agora SIM: soma aritmética, resulta 31
Repare no que mudou. Antes, idade era texto e + 1 teria concatenado; agora, após o int.Parse, idade é um número de verdade, e idade + 1 faz a soma aritmética, produzindo 31. A conversão foi a ponte que faltava. Juntando com a leitura da aula anterior, podemos finalmente ler e calcular:
Console.Write("Digite sua idade: ");
string entrada = Console.ReadLine();
int idade = int.Parse(entrada); // converte o que foi digitado em número
Console.WriteLine("No ano que vem você terá " + (idade + 1) + " anos.");
(Note os parênteses em (idade + 1): eles garantem que a soma aconteça antes da concatenação com o texto. Sem eles, a mistura de soma e concatenação numa mesma linha poderia produzir resultados confusos — os parênteses deixam claro que primeiro se soma, depois se junta ao texto.)
O perigo da conversão ingênua
O programa acima funciona desde que o usuário colabore, digitando um número. Mas — e aqui está a lição central — o usuário nem sempre colabora. Ele pode digitar "trinta", "3o" (com a letra "o" no lugar do zero), deixar em branco, ou digitar qualquer bobagem. O que acontece então? O int.Parse não consegue interpretar aquilo como número, e ele reage da maneira mais drástica possível: ele quebra o programa. O programa é interrompido abruptamente, com uma mensagem de erro técnica, e nada mais do que viria depois é executado.
Essa é uma falha grave de robustez. Um programa que quebra diante de uma digitação errada é frágil e frustrante de usar. E o problema não é culpa do usuário — é responsabilidade nossa, como programadores, antecipar que entradas inválidas acontecerão e preparar o programa para elas. Confiar cegamente que a entrada será sempre válida é o erro número um de quem começa. Precisamos de uma forma de conversão que não quebre quando o texto não for um número, e sim nos avise educadamente que a conversão falhou.
A conversão segura: TryParse
O C# oferece exatamente essa forma segura, chamada int.TryParse (do inglês try, "tentar" — ou seja, "tente interpretar"). Em vez de quebrar quando falha, ela tenta a conversão e nos informa se deu certo ou não, entregando o número convertido separadamente. Sua forma de uso é um pouco diferente e merece explicação cuidadosa:
Console.Write("Digite sua idade: ");
string entrada = Console.ReadLine();
int idade; // declaramos a variável que receberá o número, se a conversão der certo
if (int.TryParse(entrada, out idade))
{
Console.WriteLine("No ano que vem você terá " + (idade + 1) + " anos.");
}
else
{
Console.WriteLine("Isso não parece um número válido.");
}
Há elementos novos aqui, e vamos destrinchá-los, mesmo que alguns só sejam plenamente estudados adiante. O int.TryParse(entrada, out idade) faz duas coisas ao mesmo tempo: tenta converter entrada num número e, se conseguir, coloca esse número na variável idade (é o que a palavra out sinaliza — que idade é uma variável de saída, que a ação vai preencher). Além disso, o TryParse devolve um valor de verdadeiro ou falso (um bool, da Aula #05): verdadeiro se a conversão deu certo, falso se não. Esse verdadeiro/falso é usado pelo if — uma estrutura de decisão que estudaremos em detalhe na próxima fase, mas cuja ideia intuitiva você já capta aqui: se a conversão deu certo, execute o primeiro bloco; senão (else), execute o segundo. Assim, digitar "trinta" não quebra mais nada — apenas cai no else, exibindo a mensagem de erro amigável.
Não se preocupe se o if/else e o out ainda parecerem um tanto misteriosos; eles serão aprofundados nas aulas seguintes. O que importa absorver agora é a diferença de filosofia entre as duas conversões: o int.Parse diz "confie em mim, isto é um número", e explode se estiver errado; o int.TryParse diz "vamos tentar, e eu te aviso se não der certo", permitindo que o programa reaja com elegância. Para qualquer dado vindo de um usuário, a escolha certa é quase sempre o TryParse.
Convertendo para outros tipos
O mesmo par de ferramentas existe para os outros tipos numéricos. Para converter texto em um número com casas decimais, há double.Parse e double.TryParse; para dinheiro, decimal.Parse e decimal.TryParse. Todos funcionam da mesma maneira, mudando apenas o tipo de destino:
Console.Write("Digite o preço: ");
string entrada = Console.ReadLine();
if (decimal.TryParse(entrada, out decimal preco))
{
Console.WriteLine("Com 10% de desconto: " + (preco * 0.9m));
}
else
{
Console.WriteLine("Preço inválido.");
}
(Repare que, aqui, declaramos a variável diretamente dentro do TryParse, escrevendo out decimal preco — uma forma abreviada e comum de fazer as duas coisas de uma vez: declarar a variável e recebê-la preenchida. As duas formas, declarar antes ou ali mesmo, são válidas.)
A regra geral a levar desta aula: sempre que precisar transformar o texto digitado por um usuário em um número, prefira a versão TryParse, que protege seu programa contra entradas inválidas. A versão Parse tem seu lugar — quando você tem certeza de que o texto é um número válido, por exemplo, um valor que veio de dentro do próprio programa —, mas para dados do mundo exterior, a segurança do TryParse vale cada caractere a mais que ela custa.
O mistério deixado pela entrada de dados está resolvido. Você sabe converter texto em número, conhece a forma direta com Parse e entende por que ela é perigosa: diante de uma entrada que não representa um número, o programa não avisa nem contorna — ele quebra.
A alternativa madura é TryParse, que devolve se a conversão deu certo em vez de interromper tudo, permitindo ao programa reagir com uma mensagem clara. Essa diferença entre falhar ruidosamente e tratar o erro com elegância é um dos primeiros sinais de código profissional, e ela aparece muito além da conversão de tipos.
Fontes e leituras recomendadas
- Como converter uma string em número — o guia oficial que compara
ParseeTryParse; a base desta aula. - int.TryParse (referência) — os detalhes da conversão segura, extensível a todos os tipos numéricos.
- int.Parse (referência) — a conversão direta e o que acontece quando ela falha.
- O modificador out — a explicação do
out, a variável de saída usada peloTryParse. - Conversão de tipos em C# — o panorama das conversões entre tipos, para aprofundar o tema.
Exercícios
Exercício 1
Escreva um programa que peça um número ao usuário, converta-o com int.Parse, e exiba o dobro dele. Teste digitando um número válido e confirme que funciona. Depois, teste digitando "abc" e observe o que acontece — descreva o comportamento do programa.
Ver resposta
✓ Resposta: Exemplo:
Console.Write("Digite um número: ");
int n = int.Parse(Console.ReadLine());
Console.WriteLine("O dobro é: " + (n * 2));
Com um número válido, o programa exibe o dobro corretamente. Ao digitar "abc", o int.Parse não consegue interpretar o texto como número e o programa quebra: a execução é interrompida abruptamente com uma mensagem de erro técnica, e a linha que exibiria o dobro nunca chega a rodar. Isso demonstra a fragilidade da conversão ingênua diante de entrada inválida.
Exercício 2
Reescreva o programa do exercício anterior usando int.TryParse, de modo que, se o usuário digitar algo que não seja um número, o programa exiba uma mensagem de erro amigável em vez de quebrar. Teste com uma entrada válida e uma inválida.
Ver resposta
✓ Resposta: Exemplo:
Console.Write("Digite um número: ");
string entrada = Console.ReadLine();
if (int.TryParse(entrada, out int n))
Console.WriteLine("O dobro é: " + (n * 2));
else
Console.WriteLine("Isso não é um número válido.");
Com entrada válida, exibe o dobro; com entrada inválida como "abc", cai no else e exibe a mensagem amigável, sem quebrar. O TryParse tornou o programa robusto.
Exercício 3
Explique, com suas palavras, a diferença de comportamento entre int.Parse e int.TryParse quando recebem um texto que não é um número válido. Para dados digitados por um usuário, qual dos dois é o mais apropriado, e por quê?
Ver resposta
✓ Resposta: Diante de um texto que não é número, int.Parse quebra o programa — interrompe a execução com um erro. int.TryParse não quebra: ele apenas devolve falso para indicar que a conversão não deu certo, deixando o programa decidir o que fazer (por exemplo, avisar o usuário). Para dados digitados por um usuário, o mais apropriado é o TryParse, porque a entrada humana é imprevisível e o programa deve reagir a erros com elegância, em vez de quebrar diante de uma digitação inesperada.
Exercício 4
Escreva um programa que peça ao usuário dois números (lidos e convertidos com segurança via TryParse) e exiba a soma deles. Se qualquer uma das entradas for inválida, avise o usuário. (Dica: você precisará converter cada entrada e verificar se ambas deram certo.)
Ver resposta
✓ Resposta: Exemplo:
Console.Write("Primeiro número: ");
bool ok1 = int.TryParse(Console.ReadLine(), out int a);
Console.Write("Segundo número: ");
bool ok2 = int.TryParse(Console.ReadLine(), out int b);
if (ok1 && ok2)
Console.WriteLine("A soma é: " + (a + b));
else
Console.WriteLine("Uma das entradas não era um número válido.");
Cada entrada é convertida com segurança, guardando em ok1 e ok2 se deu certo; a soma só é exibida se ambas as conversões tiverem sucesso, e qualquer entrada inválida leva à mensagem de erro. (O && significa "e"; será estudado nas estruturas de decisão, mas aqui indica "se ambas deram certo".)
Exercício 5
Sem escrever código: explique por que o texto "30" e o número 30 são coisas diferentes para o computador, e por que, para calcular com um valor digitado pelo usuário, a conversão é indispensável. Relacione com o "mistério" da aula anterior.
Ver resposta
✓ Resposta: O texto "30" e o número 30 são diferentes para o computador porque têm naturezas distintas: "30" é uma sequência de caracteres (os símbolos '3' e '0'), tratada como texto, com a qual não se faz aritmética; 30 é um valor numérico, com o qual se pode calcular. Para calcular com algo que o usuário digitou, a conversão é indispensável porque tudo o que vem do teclado chega como texto (o "mistério" da aula anterior: ReadLine sempre devolve string), e o texto precisa ser transformado num número de verdade antes que somas, multiplicações ou comparações façam sentido. A conversão é a ponte que liga o que foi digitado (texto) ao que queremos manipular (número).