Universo DC - Aprenda POO com exemplos práticos
Entender como tratar erros e exceções em C# usando Try-Catch, garantindo que o programa não trave quando algo der errado.
Uma exceção é um evento que ocorre durante a execução do programa e interrompe o fluxo normal. Pode ser causada por:
// TÓPICO: Estrutura Try-Catch
// 'try': Bloco onde colocamos código que pode gerar erro
try
{
// Código que pode gerar exceção
int resultado = 10 / 0; // Divisão por zero causa exceção
}
// 'catch': Bloco que captura e trata a exceção
catch (Exception ex)
{
// Código que executa se ocorrer exceção
Console.WriteLine($"Erro: {ex.Message}");
}
// TÓPICO: Try-Catch Básico
public void CalcularForcaRelativa(Personagem personagem1, Personagem personagem2)
{
try
{
// TÓPICO: Código que Pode Gerar Erro
// Se personagem2.Nivel for 0, causa divisão por zero
double forcaRelativa = personagem1.Nivel / personagem2.Nivel;
Console.WriteLine($"Força relativa: {forcaRelativa}");
}
catch (Exception ex)
{
// TÓPICO: Tratamento do Erro
// Captura qualquer exceção e exibe mensagem
Console.WriteLine($"Erro ao calcular força: {ex.Message}");
}
}
// TÓPICO: Try-Catch para Conversão
public void ProcessarNivel(string nivelTexto)
{
try
{
// TÓPICO: Conversão que Pode Falhar
// Se nivelTexto não for um número, causa exceção
int nivel = int.Parse(nivelTexto);
Console.WriteLine($"Nível convertido: {nivel}");
}
catch (Exception ex)
{
Console.WriteLine($"Erro ao converter nível: {ex.Message}");
}
}
// TÓPICO: Try-Catch-Finally
try
{
// Código que pode gerar exceção
int resultado = 10 / 2;
Console.WriteLine($"Resultado: {resultado}");
}
catch (Exception ex)
{
// Executa se ocorrer exceção
Console.WriteLine($"Erro: {ex.Message}");
}
finally
{
// TÓPICO: Bloco Finally
// SEMPRE executa, independente de ter erro ou não
// Útil para limpeza de recursos (fechar arquivos, conexões, etc.)
Console.WriteLine("Bloco finally sempre executa!");
}
// TÓPICO: Try-Catch-Finally com Recursos
public void SalvarPersonagem(Personagem personagem)
{
// Simulando arquivo (em código real seria FileStream)
bool arquivoAberto = false;
try
{
arquivoAberto = true;
Console.WriteLine($"Salvando {personagem.Nome}...");
// Simulando erro
if (personagem.Nome == null)
{
throw new Exception("Nome não pode ser nulo!");
}
Console.WriteLine("Salvo com sucesso!");
}
catch (Exception ex)
{
Console.WriteLine($"Erro ao salvar: {ex.Message}");
}
finally
{
// TÓPICO: Limpeza de Recursos
// Sempre fecha o arquivo, mesmo se houver erro
if (arquivoAberto)
{
Console.WriteLine("Fechando arquivo...");
arquivoAberto = false;
}
}
}
// TÓPICO: Múltiplos Catch (Exceções Específicas)
public void ProcessarPersonagem(string nome, string nivelTexto)
{
try
{
// Validação
if (string.IsNullOrEmpty(nome))
{
throw new ArgumentException("Nome não pode ser vazio!");
}
// Conversão
int nivel = int.Parse(nivelTexto);
// Divisão
int forca = 100 / nivel;
Console.WriteLine($"Personagem: {nome}, Nível: {nivel}, Força: {forca}");
}
// TÓPICO: Catch Específico para ArgumentException
catch (ArgumentException ex)
{
Console.WriteLine($"Erro de argumento: {ex.Message}");
}
// TÓPICO: Catch Específico para FormatException
catch (FormatException ex)
{
Console.WriteLine($"Erro de formato: {ex.Message}");
Console.WriteLine("O nível deve ser um número válido!");
}
// TÓPICO: Catch Específico para DivideByZeroException
catch (DivideByZeroException ex)
{
Console.WriteLine($"Erro de divisão: {ex.Message}");
Console.WriteLine("Não é possível dividir por zero!");
}
// TÓPICO: Catch Genérico (Qualquer Outra Exceção)
catch (Exception ex)
{
Console.WriteLine($"Erro inesperado: {ex.Message}");
}
}
| Tipo de Exceção | Quando Ocorre | Como Aplicar |
|---|---|---|
| Exception | Exceção genérica (base de todas) | catch (Exception ex) - Captura qualquer erro |
| ArgumentException | Argumento inválido passado para método | catch (ArgumentException ex) - Validação de parâmetros |
| ArgumentNullException | Argumento nulo quando não deveria ser | catch (ArgumentNullException ex) - Verificar null |
| FormatException | Formato de string inválido | catch (FormatException ex) - Conversão de tipos |
| DivideByZeroException | Divisão por zero | catch (DivideByZeroException ex) - Operações matemáticas |
| OverflowException | Valor muito grande para o tipo | catch (OverflowException ex) - Cálculos que excedem limite |
| IndexOutOfRangeException | Índice fora dos limites do array | catch (IndexOutOfRangeException ex) - Acesso a arrays/listas |
| NullReferenceException | Tentativa de usar objeto nulo | catch (NullReferenceException ex) - Verificar null antes de usar |
| FileNotFoundException | Arquivo não encontrado | catch (FileNotFoundException ex) - Operações com arquivos |
| InvalidOperationException | Operação inválida no estado atual | catch (InvalidOperationException ex) - Estados inconsistentes |
// TÓPICO: Lançar Exceção Manualmente
// Usamos 'throw' para lançar uma exceção quando detectamos um problema
public void ValidarPersonagem(Personagem personagem)
{
// TÓPICO: Throw com Exception Genérica
if (personagem == null)
{
throw new Exception("Personagem não pode ser nulo!");
}
// TÓPICO: Throw com ArgumentException
if (string.IsNullOrEmpty(personagem.Nome))
{
throw new ArgumentException("Nome do personagem é obrigatório!");
}
// TÓPICO: Throw com ArgumentOutOfRangeException
if (personagem.Nivel < 0)
{
throw new ArgumentOutOfRangeException("Nivel", personagem.Nivel,
"Nível não pode ser negativo!");
}
// TÓPICO: Throw com InvalidOperationException
if (personagem.Nivel > 100)
{
throw new InvalidOperationException("Nível máximo é 100!");
}
Console.WriteLine("Personagem válido!");
}
// TÓPICO: Throw em Métodos de Classe
public class Heroi : Personagem
{
public void SalvarVida()
{
// TÓPICO: Validação com Throw
if (Nivel < 10)
{
throw new InvalidOperationException(
"Herói precisa ter nível mínimo de 10 para salvar vidas!");
}
VidasSalvas++;
Console.WriteLine($"{Nome} salvou uma vida!");
}
public void UsarPoderEspecial()
{
// TÓPICO: Throw com Mensagem Personalizada
if (Nivel < 50)
{
throw new Exception(
$"{Nome} precisa ter nível 50 ou superior para usar poder especial!");
}
Console.WriteLine($"{Nome} usa poder especial!");
}
}
// TÓPICO: Usando Throw
try
{
Heroi heroiNovato = new Heroi("Novato", 5, "Liga da Justiça");
heroiNovato.SalvarVida(); // Lança exceção (nível muito baixo)
}
catch (InvalidOperationException ex)
{
Console.WriteLine($"Erro: {ex.Message}");
}
// TÓPICO: Try-Catch em Sistema Completo
public class SistemaBatalha
{
public static void IniciarBatalha(Personagem atacante, Personagem defensor)
{
try
{
// TÓPICO: Validações com Throw
if (atacante == null)
{
throw new ArgumentNullException(nameof(atacante),
"Atacante não pode ser nulo!");
}
if (defensor == null)
{
throw new ArgumentNullException(nameof(defensor),
"Defensor não pode ser nulo!");
}
if (atacante.Nivel <= 0)
{
throw new ArgumentException("Nível do atacante deve ser maior que zero!");
}
// TÓPICO: Cálculo que Pode Gerar Erro
int diferencaNivel = atacante.Nivel - defensor.Nivel;
double chanceVitoria = 50.0 + (diferencaNivel * 2.0);
// TÓPICO: Validação de Resultado
if (chanceVitoria < 0)
{
throw new InvalidOperationException("Chance de vitória calculada incorretamente!");
}
Console.WriteLine($"=== BATALHA ===");
Console.WriteLine($"{atacante.Nome} (Nível {atacante.Nivel}) vs " +
$"{defensor.Nome} (Nível {defensor.Nivel})");
Console.WriteLine($"Chance de vitória de {atacante.Nome}: {chanceVitoria:F2}%");
atacante.UsarPoder();
defensor.UsarPoder();
}
// TÓPICO: Catch Específico para ArgumentNullException
catch (ArgumentNullException ex)
{
Console.WriteLine($"Erro: Personagem não informado!");
Console.WriteLine($"Detalhes: {ex.Message}");
}
// TÓPICO: Catch Específico para ArgumentException
catch (ArgumentException ex)
{
Console.WriteLine($"Erro de validação: {ex.Message}");
}
// TÓPICO: Catch Específico para InvalidOperationException
catch (InvalidOperationException ex)
{
Console.WriteLine($"Erro de operação: {ex.Message}");
}
// TÓPICO: Catch Genérico
catch (Exception ex)
{
Console.WriteLine($"Erro inesperado: {ex.Message}");
Console.WriteLine($"Tipo: {ex.GetType().Name}");
}
// TÓPICO: Finally para Limpeza
finally
{
Console.WriteLine("Batalha finalizada.");
}
}
}
// TÓPICO: MessageBox.Show - Parâmetros Explicados
try
{
// Código que pode gerar erro
SalvarPersonagem(batman);
}
catch (Exception ex)
{
// TÓPICO: MessageBox.Show - Estrutura Completa
// MessageBox.Show(mensagem, titulo, botoes, icone)
MessageBox.Show(
$"Erro ao salvar: {ex.Message}", // Parâmetro 1: Mensagem (texto principal)
"Erro", // Parâmetro 2: Título (barra de título)
MessageBoxButtons.OK, // Parâmetro 3: Botões (OK, YesNo, etc.)
MessageBoxIcon.Error // Parâmetro 4: Ícone (Error, Warning, Info, etc.)
);
}
// TÓPICO: MessageBoxButtons - Tipos de Botões
MessageBox.Show("Mensagem", "Título", MessageBoxButtons.OK); // Apenas OK
MessageBox.Show("Mensagem", "Título", MessageBoxButtons.OKCancel); // OK e Cancelar
MessageBox.Show("Mensagem", "Título", MessageBoxButtons.YesNo); // Sim e Não
MessageBox.Show("Mensagem", "Título", MessageBoxButtons.YesNoCancel); // Sim, Não e Cancelar
MessageBox.Show("Mensagem", "Título", MessageBoxButtons.RetryCancel); // Tentar Novamente e Cancelar
MessageBox.Show("Mensagem", "Título", MessageBoxButtons.AbortRetryIgnore); // Abortar, Tentar, Ignorar
// TÓPICO: MessageBoxIcon - Tipos de Ícones
MessageBox.Show("Mensagem", "Título", MessageBoxButtons.OK, MessageBoxIcon.Error); // ❌ Ícone de erro (vermelho)
MessageBox.Show("Mensagem", "Título", MessageBoxButtons.OK, MessageBoxIcon.Warning); // ⚠️ Ícone de aviso (amarelo)
MessageBox.Show("Mensagem", "Título", MessageBoxButtons.OK, MessageBoxIcon.Information); // ℹ️ Ícone de informação (azul)
MessageBox.Show("Mensagem", "Título", MessageBoxButtons.OK, MessageBoxIcon.Question); // ❓ Ícone de pergunta
MessageBox.Show("Mensagem", "Título", MessageBoxButtons.OK, MessageBoxIcon.None); // Sem ícone
// TÓPICO: Capturando Resposta do MessageBox
DialogResult resultado = MessageBox.Show(
"Deseja realmente excluir este personagem?",
"Confirmar Exclusão",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question
);
if (resultado == DialogResult.Yes)
{
Console.WriteLine("Personagem excluído!");
}
else
{
Console.WriteLine("Operação cancelada.");
}
// TÓPICO: Try-Catch com MessageBox em Windows Forms
public void SalvarPersonagem(Personagem personagem)
{
try
{
// Validação
if (personagem == null)
{
throw new ArgumentNullException(nameof(personagem),
"Personagem não pode ser nulo!");
}
if (string.IsNullOrEmpty(personagem.Nome))
{
throw new ArgumentException("Nome do personagem é obrigatório!");
}
// Simulação de salvamento
Console.WriteLine($"Salvando {personagem.Nome}...");
// Simulação de erro (em código real seria operação de arquivo)
if (personagem.Nome == "Erro")
{
throw new Exception("Erro simulado ao salvar!");
}
// TÓPICO: MessageBox de Sucesso
MessageBox.Show(
$"Personagem '{personagem.Nome}' salvo com sucesso!",
"Sucesso",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
}
catch (ArgumentNullException ex)
{
// TÓPICO: MessageBox de Erro Específico
MessageBox.Show(
$"Erro: {ex.Message}\n\nPor favor, verifique os dados do personagem.",
"Erro de Validação",
MessageBoxButtons.OK,
MessageBoxIcon.Warning
);
}
catch (ArgumentException ex)
{
MessageBox.Show(
$"Erro de validação: {ex.Message}",
"Erro",
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
}
catch (Exception ex)
{
// TÓPICO: MessageBox de Erro Genérico
MessageBox.Show(
$"Erro ao salvar: {ex.Message}\n\nTipo: {ex.GetType().Name}",
"Erro",
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
}
}
Na próxima aula, veremos Encapsulamento e modificadores de acesso (public, private, protected).