terça-feira, 13 de novembro de 2012

C# - Tratamento de Exceções



Neste artigo trabalharemos com as denominadas Exceções no C#. Falarei um pouco das instruções utilizadas para o tratamento das mesmas. O tratamento de exceções é uma forma elegante e eficiente de propagar erros no programa em tempo de execução. Importante ter em mente que uma exceção pode ser lançada tanto pelo framework quanto pelo próprio desenvolvedor. Para quem não sabe, uma exceção representa um comportamento inesperado interrompendo o fluxo normal das instruções durante a execução de um programa. Antes de começarmos a montar um exemplo prático devemos conhecer as instruções utilizadas pelo C# para tratamento de exceções, veja a seguir para maiores detalhes:

Comando
Descrição
try
Intervalo de código onde pode ocorrer o erro.
catch
Intervalo de código onde será tratado o erro.
finally
Essa instrução é sempre executada. Geralmente utilizada quando precisamos liberar algum recurso independente se o erro ocorrer.
throw
Comando responsável para gerar exceções específicas.

Agora que conhecemos os comandos necessários para trabalhar com exceções criaremos exemplos práticos, para isto inicie um novo projeto do Visual Studio 2010 e crie uma aplicação “Windows Forms” e adicionando alguns componentes no formulário. Ver Imagem 01.

Figura 01: Formulário Inicial.


Botão Try/catch

Neste primeiro exemplo utilizaremos apenas o try/catch e logo em seguida mostraremos uma mensagem ao usuário.
Sintaxe:

Try
{
   //Bloco onde poderá ocorrer algum erro
}
catch (Exception) //Classe responsável pelo tipo de erro
{
  //Bloco onde será tratado o possível erro acima
}

Exemplo:

#region Bloco Try/Catch

private void button1_Click(object sender, EventArgs e)
{
     decimal  valor1 =  0, valor2 = 0, total = 0;

     valor1 = 100;
     valor2 = 0;
           
     try
     {
         total = valor1/valor2;

     }
     catch (Exception E)
     {
         MessageBox.Show("Ocorreu uma exceção na rotina acima! ", E.Message);
              
     }
                       
}

#endregion


Neste exemplo forçamos uma exceção, dividindo um valor por zero. A classe genérica “Exception” nos proporciona visualizar o tipo de erro utilizando a propriedade “E.Message”. Ver Mensagem do MessageBox na Figura 02.
Figura 02: Dividindo por Zero.

Botão Try/catch/Finally

Utilizando o comando Finally executamos o mesmo ocorrendo ou não um erro no bloco “Try”. Neste caso apenas mostrei uma mensagem ao usuário. Normalmente o “Finally” é muito utilizado para liberar recursos da memória como, por exemplo, um objeto criado para realizar uma conexão com o banco de dados.

Sintaxe:

Try
{
   //Bloco onde poderá ocorrer algum erro
}
catch (Exception) //Classe responsável pelo tipo de erro
{
  //Bloco onde será tratado o possível erro acima
}
finally
{
  //Bloco que sempre será executado, ocorrendo ou não erros no bloco Try
}

Exemplo:


#region Bloco Try/Catch/Finally

private void button2_Click(object sender, EventArgs e)        {
     decimal valor1 = 0, valor2 = 0, total = 0;

     valor1 = 100;
     valor2 = 0;

     try
     {
           total = valor1 / valor2;
     }
     catch (Exception E)
     {
            MessageBox.Show("Ocorreu uma exceção na rotina acima! ", E.Message);
     }
     finally
     {
            MessageBox.Show("Mesmo não ocorrendo uma exceção acima esta mensagem será exibida!");
     }
}


Seguindo os mesmos passos do exemplo anterior, neste caso adicionamos o “Finally” para mostrar uma mensagem ao usuário. Significa que mesmo não ocorrendo um erro este bloco de código será executado. Ver Imagem 03.

Figura 03: Utilizando Try/Catch/Finally.

Botão Try/Catch/Throw

O comando Throw irá invocar a Exceção gerada, vejamos a seguir um pequeno exemplo.

Sintaxe:

Try
{
}
catch (Exception E) 
{
  Throw //Chamando a exceção gerada
}
Exemplo:

#region Bloco Try/Catch/Throw

private void button3_Click(object sender, EventArgs e)
{
     decimal valor1 = 0, valor2 = 0, total = 0;
     valor1 = 100;
     valor2 = 0;

     try
     {
          total = valor1 / valor2;

     }
     catch (Exception E)
     {
          throw E;
     }
}

#endregion


Classe Exception

É muito importante aprender um pouquinho desta classe que é a base para todas as exceções. Abaixo vou descrever um pouquinho de suas propriedades.

Propriedade
Descrição
HelpLink
Possui o caminho apontando para um arquivo contendo informações de ajuda sobre a exceção que ocorreu.
InnerException
Referencia uma exceção interna.
Message
Contém a mensagem de erro.
Source
Retorna informações do sistema que gerou o erro
StackTrace
Esta propriedade contém o rastreamento de pilha. Ela pode ser usada para determinar a localização da ocorrência do erro.
TargetSite
Informações sobre o método que lançou a exceção.

Exemplo de utilização:

#region Classe Exception

private void button4_Click(object sender, EventArgs e)
{
      decimal valor1 = 0, valor2 = 0, total = 0;

      valor1 = 100;
      valor2 = 0;

      try
      {
           total = valor1 / valor2;

      }
      catch (Exception E)
      {
             
MessageBox.Show("Ocorreu uma exceção na rotina acima! \n" +
          "Tipo Erro: " + E.Message + "\n" +
          "Pilha de execução: " + E.StackTrace + "\n" + 
          "Informações do Sistema: "+E.Source + "\n" +
          "Método: "+E.TargetSite + "\n");
      }
}

#endregion

       
Ver Figura 04 para maiores detalhes.
Figura 04: Propriedades da Classe Exception.

Exceções mais utilizadas

Algumas classes de exceções são mais utilizadas, irei detalhar algumas delas para podermos aprender um pouco mais e logo em seguida montarei um exemplo básico utilizando as mesmas.

System.ArithmeticException – esta seria a classe base para as exceções que ocorrem durante as denominadas operações aritméticas, como por exemplo: System.DivideByZeroException

System.ArrayTypeMismatchException - esta é lançada quando um objeto incompatível esta sendo armazenado dentro de um array.

System.DivideByZeroException – Esta classe é clássica, aquela que é chamada quando tentamos dividir algum valor por zero. 

System.IndexOutOfRangeException - é lançada quando se tenta acesar um array usando um índice que menor que zero ou maior que o máximo índice permitido. 

System.InvalidCastException - lançada quando um uma conversão de tipo explícita de um tipo base para um tipo derivado falha em tempo de execução.

System.NullReferenceException - Lançada quando um objeto ao ser acessado possui uma referência nula. 

System.OutOfMemoryException - Lançada quando não há memória suficiente para realizar a operação. 

System.OverflowException - Lançada quando em uma operação aritmética ocorre overflow.

ArgumentException - Lançada quando um argumento fornecido para o método não é válido. 

O ideal seria montarmos uma classe específica para tratarmos nossas exceções, mas como estamos aprendendo os passos iniciais e básicos da linguagem C# não entrarei muito em detalhes neste artigo.
veja logo em seguida o exemplo concatenando vários “try..catch”.

 
 Exemplo:


#region Concatenando vários Try..Catch
private void button5_Click(object sender, EventArgs e)
{
       decimal valor1 = 0, valor2 = 0, total = 0;
       valor1 = 100;
       valor2 = 0;

       try
       { 
            total = valor1 / valor2;
       }
       catch (System.FormatException E)
       {
            MessageBox.Show("Erro - formato! ", E.Message);
       }
       catch (System.DivideByZeroException E)
       {
            MessageBox.Show("Erro - Divisão por Zero! ", E.Message.ToString());
       }
       catch (System.IndexOutOfRangeException E)
       {
            MessageBox.Show("Erro - Menor ou maior que o índice permitido! ", E.Message);
       }
       catch (System.InvalidCastException E)
       {
            MessageBox.Show("Erro - Problema de conversão! ", E.Message);
       }
       catch (System.NullReferenceException E)
       {
            MessageBox.Show("Erro - Objeto está nulo! ", E.Message);
       }
}

#endregion

Conclusão

Aprendemos neste artigo como utilizar o bloco try/catch no C# para tratamento de exceções. Podemos também criar facilmente classes para tratamento de erros. Aprendemos também um pouquinho da classe base “System.Exception”, junto com suas principais propriedades.
Fica aí a dica, abraço e até o mês que vem!

Nenhum comentário:

Postar um comentário