Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
No C#, os erros no programa em tempo de execução são propagados por meio do programa usando um mecanismo chamado exceções. As exceções são geradas pelo código que encontra um erro e capturadas pelo código que pode corrigir o erro. As exceções podem ser geradas pelo tempo de execução do .NET ou pelo código em um programa. Depois que uma exceção é gerada, ela se propaga pela pilha de chamadas até que uma instrução catch
para a exceção seja encontrada. Exceções não capturadas são tratadas por um manipulador de exceção genérico fornecido pelo sistema que exibe uma caixa de diálogo.
As exceções são representadas por classes derivadas de Exception. Essa classe identifica o tipo de exceção e contém propriedades que têm detalhes sobre a exceção. Gerar uma exceção envolve a criação de uma instância de uma classe derivada de exceção, opcionalmente configurando propriedades da exceção e, em seguida, lançando o objeto usando a throw
palavra-chave. Por exemplo:
class CustomException : Exception
{
public CustomException(string message)
{
}
}
private static void TestThrow()
{
throw new CustomException("Custom exception in TestThrow()");
}
Depois que uma exceção é lançada, o runtime verifica a instrução atual para ver se ela está dentro de um try
bloco. Se estiver, todos os blocos catch
associados ao bloco try
serão verificados para ver se eles podem capturar a exceção.
Catch
blocos normalmente especificam tipos de exceção; se o tipo do catch
bloco for do mesmo tipo que a exceção ou uma classe base da exceção, o catch
bloco poderá manipular o método. Por exemplo:
try
{
TestThrow();
}
catch (CustomException ex)
{
System.Console.WriteLine(ex.ToString());
}
Se a instrução que lança uma exceção não estiver dentro de um bloco try
ou se o bloco try
que a encerra não tiver um bloco catch
correspondente, o runtime verificará o método de chamada para uma instrução try
e blocos catch
. O runtime continuará acima na pilha de chamada, pesquisando um bloco catch
compatível. Depois que o catch
bloco é encontrado e executado, o controle é passado para a próxima instrução após esse catch
bloco.
Uma try
instrução pode conter mais de um catch
bloco. A primeira catch
instrução que pode lidar com a exceção é executada; todas as instruções a seguir catch
, mesmo que sejam compatíveis, são ignoradas. Ordenar blocos catch do mais específico (ou mais derivado) para o menos específico. Por exemplo:
using System;
using System.IO;
namespace Exceptions
{
public class CatchOrder
{
public static void Main()
{
try
{
using (var sw = new StreamWriter("./test.txt"))
{
sw.WriteLine("Hello");
}
}
// Put the more specific exceptions first.
catch (DirectoryNotFoundException ex)
{
Console.WriteLine(ex);
}
catch (FileNotFoundException ex)
{
Console.WriteLine(ex);
}
// Put the least specific exception last.
catch (IOException ex)
{
Console.WriteLine(ex);
}
Console.WriteLine("Done");
}
}
}
Antes que o catch
bloco seja executado, o runtime verifica se há finally
blocos. Os blocos Finally
permitem que o programador limpe qualquer estado ambíguo que pode ser deixado de um bloco try
cancelado ou libere quaisquer recursos externos (como identificadores de gráfico, conexões de banco de dados ou fluxos de arquivo) sem esperar o coletor de lixo no runtime finalizar os objetos. Por exemplo:
static void TestFinally()
{
FileStream? file = null;
//Change the path to something that works on your machine.
FileInfo fileInfo = new System.IO.FileInfo("./file.txt");
try
{
file = fileInfo.OpenWrite();
file.WriteByte(0xF);
}
finally
{
// Closing the file allows you to reopen it immediately - otherwise IOException is thrown.
file?.Close();
}
try
{
file = fileInfo.OpenWrite();
Console.WriteLine("OpenWrite() succeeded");
}
catch (IOException)
{
Console.WriteLine("OpenWrite() failed");
}
}
Se WriteByte()
gerar uma exceção, o código no segundo bloco try
que tentar reabrir o arquivo falharia se file.Close()
não for chamado, e o arquivo permaneceria bloqueado. Como finally
os blocos são executados mesmo se uma exceção for lançada, o finally
bloco no exemplo anterior permite que o arquivo seja fechado corretamente e ajuda a evitar um erro.
Se nenhum bloco compatível catch
for encontrado na pilha de chamadas após a geração de uma exceção, ocorrerá uma das três coisas:
- Se a exceção estiver dentro de um finalizador, o finalizador será anulado e o finalizador base, se houver, será chamado.
- Se a pilha de chamadas contiver um construtor estático ou um inicializador de campo estático, uma TypeInitializationException será gerada, com a exceção original atribuída à propriedade InnerException da nova exceção.
- Se o início do thread for atingido, o thread será encerrado.