Desafio C#
Filtro com when e relançamento
Enunciado
Crie um método ProcessarPagamento(decimal valor) que lança SaldoInsuficienteException com a propriedade SaldoAtual. No Main, capture essa exceção usando um filtro when que só trata se SaldoAtual < 100. Caso contrário, relance a exceção com throw;. Use finally para registrar 'Pagamento processado.'
Requisitos
- A exceção
SaldoInsuficienteExceptiondeve ter uma propriedadeSaldoAtual. - O
catchdeve usarwhen (ex.SaldoAtual < 100)para tratar apenas saldo baixo. - Se o filtro não for atendido, a exceção deve ser relançada com
throw;e capturada por umcatchexterno. - O bloco
finallydeve exibir 'Pagamento processado.'
Código inicial
using System;
public class SaldoInsuficienteException : Exception
{
public decimal SaldoAtual { get; }
public SaldoInsuficienteException(decimal saldoAtual)
: base($"Saldo insuficiente: {saldoAtual:C}")
{
SaldoAtual = saldoAtual;
}
}
class Program
{
static void ProcessarPagamento(decimal valor)
{
// TODO: lançar exceção se valor > saldo (simule saldo = 50)
}
static void Main()
{
try
{
ProcessarPagamento(150);
}
catch (SaldoInsuficienteException ex) when (ex.SaldoAtual < 100)
{
Console.WriteLine($"Tratado: {ex.Message}");
}
catch (SaldoInsuficienteException ex)
{
Console.WriteLine($"Não tratado: {ex.Message}");
throw;
}
finally
{
Console.WriteLine("Pagamento processado.");
}
}
}
Saída esperada
Não tratado: Saldo insuficiente: R$ 50,00
Pagamento processado.
Unhandled exception. SaldoInsuficienteException: Saldo insuficiente: R$ 50,00
... (stack trace)
Ver dica
O filtro when avalia a condição antes de entrar no catch. Se falsa, a exceção continua procurando outro catch.
Mostrar solução
using System;
public class SaldoInsuficienteException : Exception
{
public decimal SaldoAtual { get; }
public SaldoInsuficienteException(decimal saldoAtual)
: base($"Saldo insuficiente: {saldoAtual:C}")
{
SaldoAtual = saldoAtual;
}
}
class Program
{
static void ProcessarPagamento(decimal valor)
{
decimal saldo = 50m; // saldo fixo para exemplo
if (valor > saldo)
throw new SaldoInsuficienteException(saldo);
Console.WriteLine("Pagamento aprovado.");
}
static void Main()
{
try
{
ProcessarPagamento(150);
}
catch (SaldoInsuficienteException ex) when (ex.SaldoAtual < 100)
{
Console.WriteLine($"Tratado: {ex.Message}");
}
catch (SaldoInsuficienteException ex)
{
Console.WriteLine($"Não tratado: {ex.Message}");
throw; // relança a exceção original
}
finally
{
Console.WriteLine("Pagamento processado.");
}
}
}
Passo a passo
SaldoInsuficienteExceptiontem a propriedadeSaldoAtualpara dar contexto ao erro.ProcessarPagamentosimula saldo 50 e lança a exceção se o valor for maior.- No
Main, o primeirocatchusawhen (ex.SaldoAtual < 100). Como o saldo é 50, a condição é verdadeira e a mensagem 'Tratado' é exibida. - O
finallysempre executa, imprimindo 'Pagamento processado.'. - Se o saldo fosse >= 100, o primeiro
catchseria ignorado, o segundocatchcapturaria e relançaria comthrow;, resultando em exceção não tratada.
Por que funciona
O filtro when permite capturar a exceção apenas sob certa condição, evitando if dentro do catch. O throw; relança a exceção preservando o stack trace original, diferente de throw ex; que o reinicia.
Erros comuns
- Usar
throw ex;em vez dethrow;: perde-se o stack trace original, dificultando o diagnóstico. - Filtro
whencom efeitos colaterais: o filtro deve ser uma expressão pura; efeitos colaterais podem ser executados duas vezes. - Ordem dos
catch: capturar o tipo mais genérico primeiro impede que os específicos sejam alcançados.
Outra forma de resolver
Usar if dentro de um único catch para decidir se trata ou relança. O filtro when é preferível por manter a lógica de decisão fora do bloco catch.
Saída esperada
Não tratado: Saldo insuficiente: R$ 50,00
Pagamento processado.
Unhandled exception. SaldoInsuficienteException: Saldo insuficiente: R$ 50,00
... (stack trace)