Compartilhar via


Usando exceções (guia de programação de C#)

No C#, erros no programa em tempo de execução são propagados por meio do programa usando um mecanismo chamado de exceções. Exceções são lançadas pelo código encontra um erro e capturadas pelo código que pode corrigir o erro. Exceções podem ser geradas pela.NET Framework common language runtime (CLR) ou pelo código em um programa. Depois que uma exceção é lançada, ele se propaga para cima a pilha de chamadas até um catch se encontra a instrução para a exceção. Exceções não capturadas são tratadas por um manipulador de exceção genérico fornecida pelo sistema que exibe uma caixa de diálogo.

Exceções são representadas por classes derivadas de Exception. Essa classe identifica o tipo de exceção e contém propriedades que possuem detalhes sobre a exceção. Lançando uma exceção envolve a criação de uma instância de uma classe derivada da exceção, opcionalmente Configurando propriedades da exceção e, em seguida, lançando o objeto usando o throw palavra-chave. Por exemplo:


class CustomException : Exception
{
    public CustomException(string message)
    {

    }

}
private static void TestThrow()
{
    CustomException ex =
        new CustomException("Custom exception in TestThrow()");

    throw ex;
}

Após uma exceção é lançada, o runtime verifica a instrução atual para ver se ele está dentro de um try bloco. Se for, qualquer catch blocos associados a try bloco são verificados para ver se eles podem capturar a exceção. Catchblocos geralmente especificam os tipos de exceção; Se o tipo da catch bloco é o mesmo tipo que a exceção ou uma classe base da exceção, o catch bloco pode lidar com o método. Por exemplo:

static void TestCatch()
{
    try
    {
        TestThrow();
    }
    catch (CustomException ex)
    {
        System.Console.WriteLine(ex.ToString());
    }
}

Se a instrução que lança uma exceção não estiver dentro uma try bloco ou se a try bloco que envolve a ele não tem correspondente catch bloco, o runtime verifica o método de chamada para um try instrução e catch blocos. O tempo de execução continua na pilha de chamada, procurando por um compatível com o catch bloco. Após a catch bloco é encontrado e executado, o controle é passado para a próxima instrução depois que catch bloco.

A try instrução pode conter mais de uma catch bloco. O primeiro catch que pode tratar a exceção de instrução é executada; qualquer seguinte catch instruções, mesmo se eles são compatíveis, são ignoradas. Portanto, catch blocos sempre devem ser ordenados da mais específica (ou derivados de maioria) à menos específica. Por exemplo:

static void TestCatch2()
{
    System.IO.StreamWriter sw = null;
    try
    {
        sw = new System.IO.StreamWriter(@"C:\test\test.txt");
        sw.WriteLine("Hello");
    }

    catch (System.IO.FileNotFoundException ex)
    {
        // Put the more specific exception first.
        System.Console.WriteLine(ex.ToString());  
    }

    catch (System.IO.IOException ex)
    {
        // Put the less specific exception last.
        System.Console.WriteLine(ex.ToString());  
    }
    finally 
    {
        sw.Close();
    }

    System.Console.WriteLine("Done"); 
}

Antes de catch bloco é executado, o runtime verifica finally blocos. Finallyblocos de habilitar o programador limpar qualquer estado ambíguo que poderia ser deixado de um anuladas try bloco, ou para liberar recursos externos (como, por exemplo, as alças de elementos gráficos, conexões de banco de dados ou fluxos de arquivo) sem aguardar que o coletor de lixo no runtime finalizar a objetos. Por exemplo:

static void TestFinally()
{
    System.IO.FileStream file = null;
    //Change the path to something that works on your machine.
    System.IO.FileInfo fileInfo = new System.IO.FileInfo(@"C:\file.txt");

    try
    {
        file = fileInfo.OpenWrite();
        file.WriteByte(0xF);
    }
    finally
    {
        // Closing the file allows you to reopen it immediately - otherwise IOException is thrown.
        if (file != null)
        {
            file.Close();
        }
    }

    try
    {
        file = fileInfo.OpenWrite();
        System.Console.WriteLine("OpenWrite() succeeded");
    }
    catch (System.IO.IOException)
    {
        System.Console.WriteLine("OpenWrite() failed");
    }
}

Se WriteByte() emitiu uma exceção, o código na segunda try que tenta reabrir o arquivo de bloqueio falhará se file.Close() não é chamado e o arquivo permanecerá bloqueado. Porque finally blocos são executados, mesmo se uma exceção é lançada, a finally bloco no exemplo anterior permite que o arquivo a ser fechado corretamente e ajuda a evitar um erro.

Se não compatível com o catch bloco for encontrada na pilha de chamadas após uma exceção é lançada, uma das três fatos ocorre:

  • Se a pilha de chamadas contiver um construtor estático, ou um inicializador Campo estático, é acionada, com a exceção original atribuída à propriedade InnerException da Nova Exceção. um TypeInitializationException

  • Se a pilha de chamada contém um construtor estático ou um inicializador de campo estático, um TypeInitializationException é lançada, com a exceção original atribuída para o InnerException propriedade de exceção de novo.

  • Se o início do thread é alcançado, o segmento é encerrado.

Consulte também

Referência

Exceptions and Exception Handling (C# Programming Guide)

Conceitos

C# Programming Guide