Exceptions é qualquer condição de erro ou comportamento inesperado encontrado por um programa em execução.
No .NET, uma exceção é um objeto herdado da classe System.Exception
. E quando essa exceção é lançada, ela é propagada na pilha de chamadas de métodos em execução até que seja capturada (tratada) ou o programa seja encerrado.
Tipos de Exception
Existem duas sub-classes principais dentro do System.Exception
.
- SystemException: Excessões geradas pelo .NET
- ApplicationException: Tipo recomendado para criações de exceptions personalizadas.
A existência dessas duas classes é uma forma de permitir diferenciar exceções de sistemas e exceções de sua aplicação.
Estrutura try-cath
Essa estrutura é utilizada para capturar e tratar exceções que ocorrem durante a execução do programa, permitindo lidar com erros de maneira controlada e sem interromper a aplicação
TRY
O bloco try
contém o código que pode gerar uma exceção, se uma exceção ocorrer dentro desse bloco, o fluxo de execução será transferido para o bloco catch
correspondente.
CATCH
Captura a exceção lançada no bloco try
e executa o código do tratamento para essa exceção, pode haver múltiplos blocos catch
para capturar diferentes tipos de exceções.
FINALLY (opcional)
Executando sempre, independente de uma exceção ser lançada ou não, normalmente é usado para libera recursos (fechar arquivo, liberar memória, etc.).
Estrutura básica
try
{
// Código que pode gerar uma exceção
}
catch (ExceptionType ex)
{
// Código para tratar a exceção
}
finally
{
// Código que será executado sempre (opcional)
}
Exemplo de uso
Esse é um exemplo interessante pois nesse caso existem várias características de tratamento de erro
-
Múltiplos
catch
: Você pode ter múltiplos blocoscatch
para capturar diferentes tipos de exceções. -
finally
: Executado sempre, mesmo que ocorra uma exceção, garantindo que recursos sejam sempre liberados. -
Exceções específicas: O uso de exceções específicas (
IndexOutOfRangeException
,NullReferenceException
) é preferível para capturar erros com precisão.
try
{
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers[5]); // Isso causará uma exceção
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("Erro: Tentativa de acessar um índice inválido.");
}
catch (Exception ex)
{
Console.WriteLine($"Erro genérico: {ex.Message}");
}
finally
{
Console.WriteLine("Bloco 'finally' executado.");
}
Exceptions personalizadas
É possível criar exceções personalizadas estendendo a classe base Exception
. São úteis quando você quer definir erros específicos para o seu domínio de aplicação ou fornecer mensagens de erros mais detalhadas.
Estrutura básica
public class MinhaExcecaoPersonalizada : Exception
{
// Construtor padrão
public MinhaExcecaoPersonalizada()
{
}
// Construtor com mensagem de erro
public MinhaExcecaoPersonalizada(string mensagem)
: base(mensagem)
{
}
// Construtor com mensagem de erro e exceção interna
public MinhaExcecaoPersonalizada(string mensagem, Exception inner)
: base(mensagem, inner)
{
}
}
Exemplo de uso
Vou mostrar um exemplo de uma exceção personalizada chamada SaldoInsuficienteException
em um cenário de saque bancário:
public class SaldoInsuficienteException : Exception
{
public decimal SaldoAtual { get; }
public SaldoInsuficienteException()
: base("Saldo insuficiente para completar a operação.")
{
}
public SaldoInsuficienteException(string mensagem)
: base(mensagem)
{
}
public SaldoInsuficienteException(string mensagem, decimal saldoAtual)
: base(mensagem)
{
SaldoAtual = saldoAtual;
}
public SaldoInsuficienteException(string mensagem, Exception inner)
: base(mensagem, inner)
{
}
}
// Classe ContaBancaria com lógica de saque
public class ContaBancaria
{
public decimal Saldo { get; private set; }
public ContaBancaria(decimal saldoInicial)
{
Saldo = saldoInicial;
}
public void Sacar(decimal quantia)
{
if (quantia > Saldo)
{
// Lança a exceção personalizada quando o saldo é insuficiente
throw new SaldoInsuficienteException(
$"Você tentou sacar {quantia:C}, mas seu saldo é de {Saldo:C}.", Saldo);
}
Saldo -= quantia;
}
}
// Programa principal
class Program
{
static void Main()
{
// Inicializa a conta com saldo de 100
ContaBancaria conta = new ContaBancaria(100);
try
{
// Tenta sacar 150, o que vai estourar uma exceção
conta.Sacar(150);
}
catch (SaldoInsuficienteException ex)
{
// Captura e exibe a mensagem de erro personalizada
Console.WriteLine("Erro ao sacar dinheiro:");
Console.WriteLine(ex.Message); // Mensagem da exceção
Console.WriteLine($"Saldo atual: {ex.SaldoAtual:C}"); // Saldo atual armazenado na exceção
}
}
}