Exceções personalizadas C#

Resumo : neste tutorial, você aprenderá sobre exceções personalizadas em C# e como criar e usar uma exceção personalizada em seu programa.

Introdução às exceções personalizadas do C#

C# fornece muitas classes de exceção integradas. Às vezes, essas classes de exceção integradas não são suficientes para descrever o erro no seu aplicativo. Nesse caso, você pode definir classes de exceção personalizadas.

Por definição, uma exceção personalizada é uma exceção criada para representar um erro específico em seu aplicativo.

Para criar uma exceção personalizada, você define uma classe que herda da System.Exceptionclasse. Por convenção, uma classe de exceção termina Exceptioncom MyCustomException:

class MyCustomException: Exception
{
}Linguagem de código:  C#  ( cs )

Uma classe de exceção personalizada deve ter três construtores padrão:

class MyCustomException: Exception
{
    MyCustomException(): base() { }
    MyCustomException(string message) : base(message) { }
    MyCustomException(string message, Exception innerException) : base(message, innerException) { }
}Linguagem de código:  C#  ( cs )

Neste exemplo:

  • O primeiro construtor é um construtor padrão que não aceita argumentos.
  • O segundo construtor recebe uma mensagem de string que descreve a exceção.
  • O terceiro construtor recebe uma mensagem e uma exceção interna, que você pode usar para encadear exceções e descrever o erro com mais detalhes.

Uma classe de exceção personalizada também pode ter propriedades adicionais para fornecer mais informações sobre o erro que ocorre.

Exemplo de exceção personalizada C#

Vamos dar uma olhada em um exemplo de uso de uma exceção personalizada.

using static System.Console;

public class Account
{
    private decimal balance;
    public decimal Balance => balance;

    public Account(decimal initialBalance = 0)
    {
        if (initialBalance < 0)
        {
            throw new ArgumentOutOfRangeException($"The {nameof(initialBalance)} must be zero or positive.");
        }
        balance = initialBalance;
    }

    public Account Withdraw(decimal amount)
    {
        if (amount > Balance)
        {
            throw new ArgumentOutOfRangeException(
                nameof(amount),
                $"Could not withdraw an amount ({amount:C}) that is more than balance ({Balance:C})"
            );
        }

        balance -= amount;
        return this;
    }
    public Account Deposit(decimal amount)
    {
        if (amount <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(amount));
        }
        balance += amount;
        return this;
    }
}

public class Program
{
    public static void Main(string[] args)
    {

        var account = new Account(100);
        try
        {
            account.Withdraw(200);
        }
        catch (ArgumentOutOfRangeException ex)
        {
            WriteLine(ex.Message);
        }
        catch (Exception ex)
        {
            WriteLine(ex.Message);
        }

        ReadLine();
    }
}Linguagem de código:  C#  ( cs )

Saída:

Could not withdraw an amount ($200.00) that exceeds the balance ($100.00) (Parameter 'amount')Linguagem de código:  C#  ( cs )

Como funciona.

Primeiro, defina uma Accountclasse que represente uma conta bancária com saldo. A Accountclasse possui dois métodos para depositar e sacar dinheiro. Esses métodos usam uma classe de exceção integrada ArgumentOutOfRangeExceptionpara evitar operações inválidas.

Segundo, crie um novo Accountobjeto no Main()método da Programclasse com saldo inicial de 100. Em seguida, tente sacar 200 da conta usando o Withdraw()método.

Como o saldo é insuficiente, o Withdraw()método lança um arquivo ArgumentOutOfRangeException.

O bloco catch trata a ArgumentOutOfRangeExceptionexceção exibindo a mensagem de erro no console.

O programa funciona bem, exceto que ArgumentOutOfRangeExceptionnão é muito expressivo e a mensagem de erro não mostra o déficit.

Para melhorar isso, podemos criar uma nova exceção personalizada da seguinte forma:

using static System.Console;

public class InsufficientFundException : Exception
{
    public decimal Deficit
    {
        get;
        set;
    }
    public InsufficientFundException()
        : base()
    {
    }

    public InsufficientFundException(
        string message
    )
        : base(message)
    {
    }

    public InsufficientFundException(
      string message,
      Exception innerException
  ) : base(message, innerException)
    {

    }

    public InsufficientFundException(decimal deficit)
    {
        Deficit = deficit;
    }


    public override string Message =>
         $"{base.Message} Could not withdraw due to a deficit of {Deficit:C}";


}
public class Account
{

    private decimal balance;
    public decimal Balance => balance;

    public Account(decimal initialBalance = 0)
    {
        if (initialBalance < 0)
        {
            throw new ArgumentOutOfRangeException($"The {nameof(initialBalance)} must be zero or positive.");
        }
        balance = initialBalance;
    }

    public Account Withdraw(decimal amount)
    {
        if (amount > Balance)
        {
            var deficit = amount - Balance;
            throw new InsufficientFundException(deficit);

        }

        balance -= amount;
        return this;
    }
    public Account Deposit(decimal amount)
    {
        if (amount <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(amount));
        }
        balance += amount;
        return this;
    }
}

public class Program
{
    public static void Main(string[] args)
    {

        var account = new Account(100);
        try
        {
            account.Withdraw(200);
        }
        catch (InsufficientFundException ex)
        {
            WriteLine(ex.Message);
        }
        catch (Exception ex)
        {
            WriteLine(ex.Message);
        }

        ReadLine();
    }
}Linguagem de código:  C#  ( cs )

Saída:

Exception of type 'InsufficientFundException' was thrown. Could not withdraw due to a deficit of $100.00Linguagem de código:  C#  ( cs )

Como funciona.

Primeiro, defina uma nova classe de exceção personalizada chamada InsufficientFundExceptionque herde da Exceptionclasse.

public class InsufficientFundException : Exception
{
    public decimal Deficit
    {
        get;
        set;
    }
    public InsufficientFundException()
        : base()
    {
    }

    public InsufficientFundException(
        string message
    )
        : base(message)
    {
    }

    public InsufficientFundException(
      string message,
      Exception innerException
  ) : base(message, innerException)
    {

    }

    public InsufficientFundException(decimal deficit)
    {
        Deficit = deficit;
    }


    public override string Message =>
         $"{base.Message} Could not withdraw due to a deficit of {Deficit:C}";

}Linguagem de código:  C#  ( cs )

A InsufficientFundExceptionclasse implementa três construtores padrão.

A InsufficientFundExceptionclasse também possui um quarto construtor que leva um parâmetro decimal chamado deficit, que representa o déficit ao tentar sacar um valor que ultrapassa o saldo. Este construtor define a Deficitpropriedade para o parâmetro deficit.

A InsufficientFundExceptionclasse estende a Messagepropriedade da Exceptionclasse. Ele concatena a Messageclasse base com uma mensagem personalizada que inclui o arquivo deficit.

No Withdraw()método da Accountclasse, em vez de lançar o ArgumentOutOfRangeException, ele lança a InsufficientFundExceptionexceção e passa o deficitpara o seu construtor.

public Account Withdraw(decimal amount)
{
    if (amount > Balance)
    {
        var deficit = amount - Balance;
        throw new InsufficientFundException(deficit);
    }

    balance -= amount;
    return this;
}Linguagem de código:  C#  ( cs )

No Mainmétodo da Programclasse, em vez de capturar a ArgumentOutOfRangeExceptionexceção, capturamos ArgumentOutOfRangeExceptione exibimos a mensagem de erro no console:

public class Program
{
    public static void Main(string[] args)
    {
        var account = new Account(100);
        try
        {
            account.Withdraw(200);
        }
        catch (ArgumentOutOfRangeException ex)
        {
            WriteLine(ex.Message);
        }
        catch (Exception ex)
        {
            WriteLine(ex.Message);
        }
    }
}Linguagem de código:  C#  ( cs )

Resumo

  • Crie uma classe de exceção personalizada apenas se ela fornecer informações mais significativas e detalhadas sobre o erro em seu aplicativo.
  • Estenda a classe interna System.Exceptionpara definir uma classe de exceção personalizada.
  • Lance uma exceção personalizada usando a throwpalavra-chave seguida pelo objeto de exceção personalizada.
  • Use o try...catchbloco para capturar uma exceção personalizada especificando o tipo de exceção personalizada no catchbloco.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *