Exceções em C#
Imagine que você está cozinhando e seguindo uma receita. A receita é o seu programa, uma sequência de passos bem definida. Um dos passos diz: "adicione uma xícara de leite". Você vai até a geladeira, mas descobre que o leite acabou. O que acontece?
Sem tratamento de exceções: Você para tudo. A receita não pode continuar. O jantar está arruinado. No mundo do software, isso é um "crash". O programa para de funcionar abruptamente.
Com tratamento de exceções: A receita, prevendo essa possibilidade, tem uma nota de rodapé: "Se não tiver leite, use creme de leite ou água". Você tem uma alternativa! A receita continua, talvez com um resultado um pouco diferente, mas não falha completamente.
Isso é uma exceção: um problema inesperado que ocorre durante a execução de um programa. O tratamento de exceções é o plano que criamos para lidar com esses imprevistos de forma elegante, sem deixar o programa "quebrar".
O Bloco try-catch
A principal ferramenta para tratar exceções em C# é o bloco try-catch.
try: Colocamos dentro deste bloco o código que pode lançar uma exceção. É a nossa "tentativa".catch: Este bloco contém o código que será executado se uma exceção ocorrer dentro do blocotry. É o nosso plano B.
No exemplo acima, int.Parse("abc") não pode ser executado, então o .NET lança uma FormatException. Como o código está dentro de um bloco try, a execução normal para e o controle é passado para o bloco catch correspondente, que imprime uma mensagem de erro amigável.
O Bloco finally
E se precisarmos executar um código de "limpeza" independentemente de uma exceção ter ocorrido ou não? Por exemplo, fechar um arquivo ou uma conexão com o banco de dados. Para isso, usamos o bloco finally.
O código dentro do finally é sempre executado:
Se o bloco
tryfor concluído com sucesso.Se uma exceção for lançada e capturada por um
catch.
Diagrama de Fluxo try-catch-finally
Tratando Múltiplas Exceções
Um único bloco try pode gerar diferentes tipos de exceções. Podemos ter vários blocos catch para tratar cada tipo de erro de uma maneira específica.
Lançando Exceções com throw
Às vezes, nós mesmos precisamos criar e lançar exceções. Isso é útil quando detectamos uma condição de erro que impede nosso método de funcionar corretamente. Usamos a palavra-chave throw para isso.
Boas Práticas
Seja Específico: Capture os tipos de exceção mais específicos primeiro (
FormatException,IOException) e os mais genéricos (Exception) por último.Não Capture o que Você Não Pode Resolver: Se você não sabe o que fazer com uma exceção, é melhor não capturá-la. Deixe que um nível mais acima na "pilha de chamadas" (call stack) a trate.
Não Use Exceções para Controle de Fluxo: Exceções são para erros excepcionais, não para situações normais. Usá-las para controle de fluxo (como um
if/else) é muito ineficiente.Use
finallyouusingpara Liberar Recursos: Sempre garanta que recursos como arquivos, conexões de rede ou de banco de dados sejam liberados. O blocousingem C# é uma forma mais concisa e segura de fazer isso para objetos que implementamIDisposable.