Parâmetros e Conversão de Dados em C# com VS Code
Objetivo da Aula:
Capacitar os alunos a criar programas C# que interagem com o ambiente, recebendo e processando parâmetros da linha de comando, e a dominar as diversas formas de conversão de dados, incluindo implícita, explícita, System.Convert
, e os conceitos de Boxing e Unboxing.
Público-Alvo:
Estudantes de programação com conhecimento básico em C# e uso do VS Code.
Duração Estimada:
1h30min - 2h (dependendo do ritmo dos alunos e da profundidade das discussões/exercícios).
Materiais Necessários:
Computadores com Visual Studio Code (VS Code) e SDK do .NET instalados e configurados.
Quadro ou lousa para anotações.
Parte 1: Recebimento e Tratamento de Parâmetros (45-60 minutos)
1. Introdução (5 minutos)
Professor: "Olá a todos! Hoje vamos aprender como nossos programas C# podem ser mais inteligentes e flexíveis, aceitando informações de fora (parâmetros da linha de comando) e como manipular esses dados (conversões). Isso é super útil para criar ferramentas dinâmicas!"
Professor: Perguntar aos alunos: "Alguém já viu programas que vocês executam e podem colocar informações extras depois do nome do programa?" (Ex:
git commit -m "minha mensagem"
). Explicar que é isso que vamos aprender a fazer.
2. Configurando o Projeto no VS Code (10 minutos - Mão na Massa)
Professor: Instruir os alunos a abrir o VS Code.
Professor: Abrir o Terminal Integrado (
Ctrl+'
).Professor: Comandos no terminal:
Bash
dotnet new console -o ParametroApp cd ParametroApp code .
Professor: "Lembrem-se, o
code .
vai reabrir o VS Code na pasta do nosso novo projeto. Isso é muito prático!"
3. Entendendo o Main
e os Parâmetros (string[] args
) (10 minutos)
Professor: Abrir
Program.cs
.Professor: Explicar a assinatura do método
Main
:static void Main(string[] args)
.Focar no
string[] args
. "Esteargs
é um array de strings, e é para cá que o C# joga todas as palavras que digitarmos depois do nome do nosso programa."Explicar que cada item no array é um parâmetro.
Professor: Exemplo Prático (Exibir Parâmetros Simples):
// Program.cs namespace ParametroApp { internal class Program { static void Main(string[] args) { if (args.Length > 0) { Console.WriteLine("Parâmetros recebidos:"); for (int i = 0; i < args.Length; i++) { Console.WriteLine($"Parâmetro {i + 1}: {args[i]}"); } } else { Console.WriteLine("Nenhum parâmetro foi fornecido."); Console.WriteLine("Tente executar o programa com parâmetros, por exemplo:"); Console.WriteLine("dotnet run -- primeiro segundo terceiro"); } } } }
Professor: Execução e Explicação do
--
:dotnet run
(sem parâmetros)dotnet run -- meu parametro de teste
(com parâmetros)Crucial: Explicar o
--
. "Este--
é um separador. Ele diz ao comandodotnet run
: 'O que vem depois de mim não é para você,dotnet run
, é para o meu programa C#!' Sem ele, odotnet
tentaria interpretar 'meu' como uma opção dele mesmo."
4. Tratando Parâmetros: Um Exemplo Prático de Saudações (15-20 minutos)
Professor: "Agora que sabemos como receber, vamos aprender a tratar esses parâmetros. Vamos fazer um programa de saudação personalizada!"
Professor: Explicar a ideia de "flags" ou "opções" (como
-n
para nome,-s
para saudação).Professor: Código no
Program.cs
:// Program.cs namespace ParametroApp { internal class Program { static void Main(string[] args) { string nome = "Visitante"; string saudacaoTipo = "Olá"; for (int i = 0; i < args.Length; i++) { if (args[i] == "-n" || args[i] == "--nome") { if (i + 1 < args.Length) { nome = args[i + 1]; i++; // Avança para pular o valor do nome } else { Console.WriteLine("Erro: O argumento -n ou --nome requer um valor."); } } else if (args[i] == "-s" || args[i] == "--saudacao") { if (i + 1 < args.Length) { saudacaoTipo = args[i + 1]; i++; // Avança para pular o valor da saudação } else { Console.WriteLine("Erro: O argumento -s ou --saudacao requer um valor."); } } else { Console.WriteLine($"Aviso: Parâmetro '{args[i]}' não reconhecido."); } } Console.WriteLine($"{saudacaoTipo}, {nome}!"); } } }
Professor: Testes com alunos:
dotnet run
dotnet run -- -n Alice
dotnet run -- -s BoaNoite -n Bob
dotnet run -- -n Carla -s Olá
dotnet run -- -n David parametro_extra
Professor: Reforçar:
args.Length
,for
loop para iterar, tratamento de erro (if (i + 1 < args.Length)
).
Parte 2: Conversão de Dados (45-60 minutos)
1. Introdução à Conversão (5 minutos)
Professor: "Perfeito! Agora que nossos programas podem receber dados, precisamos saber como transformá-los. E se o usuário digitar '10' como texto e precisarmos somar com outro número? Aí entram as conversões de dados."
Professor: "Vamos criar um novo projeto para focar só nisso."
2. Configurando o Novo Projeto de Conversão (5 minutos - Mão na Massa)
Professor: No terminal, criar um novo projeto:
Bash
cd .. dotnet new console -o ConversaoDadosApp cd ConversaoDadosApp code .
3. Conversão Implícita (10 minutos)
Professor: "A conversão implícita é a mais 'tranquila'. Ela acontece automaticamente quando o C# tem certeza que não haverá perda de dados. Pensem em colocar um copo de água num balde: a água cabe, e o balde é maior."
Professor: Código no
Program.cs
:// Program.cs namespace ConversaoDadosApp { internal class Program { static void Main(string[] args) { Console.WriteLine("--- Conversão Implícita ---"); int meuInt = 100; long meuLong = meuInt; // int para long Console.WriteLine($"int para long: {meuInt} -> {meuLong}"); int outroInt = 250; float meuFloat = outroInt; // int para float Console.WriteLine($"int para float: {outroInt} -> {meuFloat}"); float outroFloat = 123.45f; double meuDouble = outroFloat; // float para double Console.WriteLine($"float para double: {outroFloat} -> {meuDouble}"); Console.WriteLine("\n--- Fim da Conversão Implícita ---\n"); } } }
Professor: Executar:
dotnet run
Professor: "Notem que o código funciona sem reclamar. O compilador do C# é inteligente e sabe que
long
pode guardar qualquerint
, por exemplo."
4. Conversão Explícita (Casting) (15 minutos)
Professor: "Agora, e se for o contrário? Tentar colocar um balde de água num copo? Aí temos um problema! O compilador não vai fazer isso sozinho, porque pode haver perda de dados. Precisamos dizer a ele explicitamente que estamos cientes do risco, usando o casting."
Professor: Código no
Program.cs
:// ... (Manter código anterior ou apagar) ... Console.WriteLine("--- Conversão Explícita (Casting) ---"); double valorDouble = 9.99; int valorInt = (int)valorDouble; // double para int (truncamento) Console.WriteLine($"double para int: {valorDouble} -> {valorInt}"); long numeroLongoGrande = 2147483648L; // Maior que o máximo de int int numeroInt2 = (int)numeroLongoGrande; // long para int (estouro de inteiro) Console.WriteLine($"long para int (valor maior): {numeroLongoGrande} -> {numeroInt2}"); Console.WriteLine("Atenção: Houve perda de dados neste caso (estouro de inteiro)!"); char meuChar = 'A'; int charParaInt = (int)meuChar; // char para int (valor ASCII/Unicode) Console.WriteLine($"char para int: '{meuChar}' -> {charParaInt} (valor ASCII/Unicode)"); Console.WriteLine("\n--- Fim da Conversão Explícita ---\n");
Professor: Executar:
dotnet run
Professor: "Observem a sintaxe
(TipoDesejado)variavel
. É como se estivéssemos falando: 'Compilador, eu sei o que estou fazendo, pode converter, mesmo que perca dados!' Nodouble
paraint
, a parte decimal é simplesmente cortada. Nolong
paraint
, se o número for muito grande, ele 'estoura' e vira outro número, que não é o que esperávamos!"
5. Usando System.Convert
(15 minutos)
Professor: "Quando a gente lida muito com strings (textos) que na verdade representam números, ou precisa de um controle maior sobre as conversões, o
System.Convert
é nosso melhor amigo. Ele tem métodos específicos para cada tipo e é mais robusto, podendo nos avisar se algo deu errado com exceções."Professor: Código no
Program.cs
:C#
// ... (Manter código anterior ou apagar) ... Console.WriteLine("--- Usando System.Convert ---"); string textoNumero = "123"; int numeroConvertido = Convert.ToInt32(textoNumero); // string para int Console.WriteLine($"string para int: '{textoNumero}' -> {numeroConvertido}"); int outroNumero = 456; string textoOutroNumero = Convert.ToString(outroNumero); // int para string Console.WriteLine($"int para string: {outroNumero} -> '{textoOutroNumero}'"); string textoInvalido = "Olá Mundo"; try { int numeroInvalido = Convert.ToInt32(textoInvalido); } catch (FormatException) { Console.WriteLine($"Erro: Não foi possível converter '{textoInvalido}' para int. Formato inválido."); } Console.WriteLine("\n--- Fim de System.Convert ---\n");
Professor: Executar:
dotnet run
Professor: "Vejam como ele consegue converter de string para número e de número para string. E o mais importante: se a string não for um número válido, ele nos avisa com uma exceção(
FormatException
), que podemos 'pegar' com umtry-catch
para que nosso programa não trave."
6. Boxing e Unboxing (15 minutos)
Professor: "Esses são conceitos mais avançados, mas muito importantes para entender como C# lida com diferentes tipos de memória. O C# tem tipos de valor (como
int
,double
,bool
) que guardam o valor diretamente, e tipos de referência (comostring
,object
, classes) que guardam um endereço para onde o valor está na memória."Professor: Explicar Boxing: "Quando pegamos um tipo de valor e o tratamos como um
object
(que é um tipo de referência), o C# precisa 'empacotá-lo'. Isso é o Boxing. Ele cria um novo espaço na memória (no 'heap', para referências) e copia o valor para lá."Professor: Código para Boxing:
C#
// ... (Manter código anterior ou apagar) ... Console.WriteLine("--- Boxing ---"); int numeroOriginal = 123; object objetoBoxed = numeroOriginal; // Boxing: int para object Console.WriteLine($"Número Original (int): {numeroOriginal}"); Console.WriteLine($"Objeto Boxed (object): {objetoBoxed}"); Console.WriteLine($"Tipo do objeto Boxed: {objetoBoxed.GetType()}"); double pi = 3.14; object piBoxed = pi; // Boxing de um double Console.WriteLine($"Valor PI Original (double): {pi}"); Console.WriteLine($"Objeto PI Boxed (object): {piBoxed}"); Console.WriteLine($"Tipo do objeto PI Boxed: {piBoxed.GetType()}"); Console.WriteLine("\n--- Fim do Boxing ---\n");
Professor: Executar:
dotnet run
Professor: Explicar Unboxing: "Agora, se queremos pegar aquele valor que foi 'empacotado' no
object
e trazê-lo de volta para o seu tipo de valor original, fazemos o Unboxing. Mas cuidado! Para o Unboxing funcionar, você tem que 'desempacotar' para o mesmo tipo que foi empacotado. Se tentar para um tipo diferente, o C# vai reclamar feio!"Professor: Código para Unboxing:
C#
// ... (Manter código anterior ou apagar) ... Console.WriteLine("--- Unboxing ---"); object objetoBoxedInt = 456; // Primeiro, fazemos um boxing int numeroUnboxed = (int)objetoBoxedInt; // Unboxing: object de volta para int Console.WriteLine($"Objeto Boxed (int): {objetoBoxedInt}"); Console.WriteLine($"Número Unboxed (int): {numeroUnboxed}"); object objetoBoxedIntParaShort = 99; // Boxeado como int try { short numeroUnboxedParaShort = (short)objetoBoxedIntParaShort; // ERRO: Tentar unboxar int para short! } catch (InvalidCastException ex) { Console.WriteLine($"Erro no Unboxing para tipo diferente: {ex.Message}"); Console.WriteLine("Você só pode fazer unboxing para o tipo original (int, neste caso)."); } Console.WriteLine("\n--- Fim do Unboxing ---\n");
Professor: Executar:
dotnet run
Professor: "Prestem atenção ao
InvalidCastException
. Ele acontece porque, emborashort
eint
sejam números, o Unboxing exige que você volte exatamente para o tipo original que foi boxeado."
Parte 3: Exercício Prático e Discussão (15-20 minutos)
1. Proposta de Exercício (10 minutos)
Professor: "Agora é a vez de vocês colocarem a mão na massa e aplicarem tudo o que aprendemos!"
Professor: Apresentar o exercício:
Crie um novo programa de console que:
Declare uma variável
decimal
com um valor monetário (ex:150.75m
).Converta esse valor para
int
usando conversão explícita e mostre o resultado. Peça para eles comentarem a perda de precisão.Declare uma variável
string
contendo um número de telefone (ex:"123456789"
).Converta essa string para um
long
usandoSystem.Convert
e mostre o resultado.Tente converter a string
"não é um número"
para umint
usandoSystem.Convert
dentro de um blocotry-catch
para lidar com a exceção, e exiba uma mensagem de erro amigável se a conversão falhar.Declare uma variável
bool
com o valortrue
.Faça o boxing dessa variável
bool
para umobject
.Faça o unboxing do
object
de volta para umbool
.Tente fazer o unboxing do
object
(que era umbool
) para umint
dentro de umtry-catch
e explique a exceção.
2. Discussão e Dúvidas (5-10 minutos)
Professor: Abrir para perguntas enquanto os alunos trabalham ou após tentarem resolver o exercício.
Professor: Reforçar os cenários de uso para cada tipo de conversão.
Implícita: Sempre que for seguro, o C# faz sozinho.
Explícita (Casting): Quando o risco de perda de dados é aceitável e você quer forçar a conversão (ex: ignorar decimais).
System.Convert
: Melhor para conversões de/para strings e para tipos base, com bom controle de erros.Boxing/Unboxing: Para interagir com o tipo
object
ou coleções que esperamobject
s (embora genéricos sejam mais recomendados hoje), mas sabendo do impacto no desempenho e da rigidez do unboxing.
Atualizado