English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Aqui, você aprenderá a usar os blocos try, catch e finally para lidar com exceções no C#.
É necessário lidar com exceções no aplicativo para evitar que o programa travasse e para resultados inesperados, registrar exceções e continuar executando outras funcionalidades. O C# fornece suporte integrado para o tratamento de exceções usando os blocos try, catch e finally.
Sintaxe:
try { // Colocar o código aqui pode gerar uma exceção } catch { // Trate as exceções aqui } finally { // Código de limpeza final }
Bloco try:Qualquer código suspeito que possa gerar uma exceção deve ser colocado dentro de um bloco try{ }. Durante a execução, se ocorrer uma exceção, o fluxo de controle saltará para o primeiro bloco catch correspondente.
catch Bloco:O bloco catch é um bloco de tratamento de exceções onde você pode executar algumas operações, como registrar e auditar exceções. O bloco catch aceita um parâmetro do tipo de exceção, que você pode usar para obter detalhes da exceção.
finally Bloco:O bloco finally sempre será executado, independentemente de uma exceção ser lançada ou não. Normalmente, o finally deve ser usado para liberar recursos, como fechar qualquer fluxo ou objeto de arquivo aberto no bloco try.
Se você inserir caracteres não numéricos, o seguinte pode gerar uma exceção.
class Program { static void Main(string[] args) { Console.WriteLine("Enter a number: "); var num = int.Parse(Console.ReadLine()); Console.WriteLine($"Squre of {num} is {num"); * num"); } }
Para lidar com possíveis exceções no exemplo acima, envolva o código em um bloco try e, em seguida, lidar com a exceção no bloco catch, conforme mostrado a seguir.
class Program { static void Main(string[] args) { try { Console.WriteLine("Enter a number: "); var num = int.parse(Console.ReadLine()); Console.WriteLine($"Squre of {num} is {num"); * num"); } catch { Console.Write("Error occurred."); } finally { Console.Write("Re");-tente novamente com um número diferente."); } } }
No exemplo acima, estamos empacotando este código em um bloco try. Se ocorrer uma exceção dentro do bloco try, o programa saltará para o bloco catch. Dentro do bloco catch, mostraremos uma mensagem para informar o usuário sobre o erro, e dentro do bloco finally, mostraremos uma mensagem sobre as operações realizadas após a execução do programa.
O bloco try deve ser seguido por catch ou finally ou ambos os segmentos. Se o bloco try não usar catch ou finally, será gerado um erro de compilação.
Em um cenário ideal, o bloco catch deve conter um parâmetro de classe de exceção interna ou personalizada para obter detalhes de erro. A seguir, inclui o parâmetro type do Exception que captura todos os tipos de exceções.
class Program { static void Main(string[] args) { try { Console.WriteLine("Enter a number: "); var num = int.parse(Console.ReadLine()); Console.WriteLine($"Squre of {num} is {num"); * num"); } catch(Exception ex) { Console.Write("Error info:"); + ex.Message); } finally { Console.Write("Re");-tente novamente com um número diferente."); } } }
Você pode usar múltiplos blocos catch com diferentes tipos de parâmetros de exceção. Isso é chamado de filtro de exceção. Quando você deseja lidar com diferentes tipos de exceções de maneiras diferentes, o filtro de exceção é muito útil.
class Program { static void Main(string[] args) { Console.Write("Por favor, insira um número para dividir 100: "); try { int num = int.Parse(Console.ReadLine()); int result = 100 / num; Console.WriteLine("100 / {0} = {1} } catch(DivideByZeroException ex) { Console.Write("Não pode ser dividido por zero. Por favor, tente novamente."); } catch(InvalidOperationException ex) { Console.Write("Operação inválida. Por favor, tente novamente."); } catch(FormatException ex) { Console.Write("Não é um formato válido. Por favor, tente novamente."); } catch(Exception ex) { Console.Write("Ocorreu um erro! Por favor, tente novamente."); } } }
No exemplo acima, especificamos múltiplos blocos catch com diferentes tipos de exceções. Podemos exibir mensagens apropriadas ao usuário com base no erro, para que o usuário não repita o mesmo erro novamente.
Não é permitido usar um bloco catch sem parâmetros e um bloco catch com parâmetro Exception na mesma declaração try..catch, pois eles executam a mesma operação.
try { //código que pode gerar exceção } catch //Não é permitido ter tanto catch quanto catch(Exception exceção) { Console.WriteLine("Ocorreu uma exceção"); } catch(Exception ex) //Não é permitido ter tanto catch quanto catch(exceção exceção) { Console.WriteLine("Ocorreu uma exceção"); }
Além disso, o bloco catch sem parâmetros catch {} ou o bloco catch genérico catch (Exception ex){} devem ser os últimos blocos. Se houver outro bloco catch após o bloco catch {} ou catch (Exception ex), o compilador emitirá um erro.
Exemplo: captura catch inválida
try { //código que pode gerar exceção } catch { // Este bloco de captura deve ser o último bloco } catch (NullReferenceException nullEx) { Console.WriteLine(nullEx.Message); } catch (InvalidCastException inEx) { Console.WriteLine(inEx.Message); }
O bloco finally é opcional e deve estar após o bloco try ou catch. O bloco finally será executado sempre, independentemente de uma exceção ter ocorrido ou não. O bloco finally geralmente é usado para código de limpeza, como lidar com objetos não gerenciados.
Exemplo: bloco finally
static void Main(string[] args) { FileInfo file = null; try { Console.Write("Digite o nome do arquivo para escrever: "); string fileName = Console.ReadLine(); file = new FileInfo(fileName); file.AppendText("Hello World!") } catch(Exception ex) { Console.WriteLine("Ocorreu um erro: {0}", ex.Message); } finally { // Aqui, limpe o objeto arquivo; file = null; } }
finally não pode usar múltiplos blocos. Além disso, o bloco finally não pode conter palavras-chave return, continue ou break. Não permite que o controle saia do bloco finally.
C# permite try aninhado-No bloco catch. Quando você usa try aninhado-No bloco catch, a exceção será capturada no primeiro bloco correspondente após o bloco try onde ocorreu a exceção catch.
static void Main(string[] args) { var divider = 0; try { try { var result = 100/divider; } catch { Console.WriteLine("catch interno"); } } catch { Console.WriteLine("catch externo"); } }
catch bloco interno
No exemplo acima, o bloco catch executará um bloco interno porque é o primeiro bloco a lidar com todos os tipos de exceções.
Se não houver bloco catch interno que coincida com o tipo de exceção lançada, o controle fluirá para o bloco catch externo até encontrar o filtro de exceção apropriado. Veja o exemplo a seguir.
static void Main(string[] args) { var divider = 0; try { try { var result = 100/divider; } catch(NullReferenceException ex) { Console.WriteLine("catch interno"); } } catch { Console.WriteLine("catch externo"); } }
catch externo
No exemplo acima, será gerada uma exceção de tipo DivideByZeroException. Como o bloco catch interno apenas trata NullReferenceTypeException, o bloco catch externo o tratará.