Desafio C#

Propriedade calculada e init com validação

Enunciado

Crie uma classe Retangulo com propriedades Largura e Altura do tipo double, ambas com init e validação para não aceitar valores negativos. Adicione uma propriedade calculada Area que retorna Largura * Altura. No Main, crie um retângulo, exiba a área e tente criar outro com largura negativa, capturando a exceção.

Requisitos

  • Largura e Altura devem usar init e validar valores negativos com ArgumentException.
  • Area deve ser uma propriedade calculada (somente get).
  • O Main deve exibir a área de um retângulo válido e capturar a exceção de um inválido.

Código inicial

using System;

public class Retangulo
{
    // TODO: implementar Largura, Altura e Area
}

public class Program
{
    public static void Main()
    {
        // TODO: testar retângulo válido e inválido
    }
}

Saída esperada

Área: 15
Erro: Largura não pode ser negativa
Ver dica

No init, use if (value < 0) throw new ArgumentException(...). Area pode ser => Largura * Altura;.

Mostrar solução
using System;

public class Retangulo
{
    private double _largura;
    private double _altura;

    public double Largura
    {
        get => _largura;
        init
        {
            if (value < 0)
                throw new ArgumentException("Largura não pode ser negativa");
            _largura = value;
        }
    }

    public double Altura
    {
        get => _altura;
        init
        {
            if (value < 0)
                throw new ArgumentException("Altura não pode ser negativa");
            _altura = value;
        }
    }

    // Propriedade calculada: não armazena valor
    public double Area => Largura * Altura;
}

public class Program
{
    public static void Main()
    {
        var r1 = new Retangulo { Largura = 5, Altura = 3 };
        Console.WriteLine($"Área: {r1.Area}");

        try
        {
            var r2 = new Retangulo { Largura = -2, Altura = 4 };
        }
        catch (ArgumentException ex)
        {
            Console.WriteLine($"Erro: {ex.Message}");
        }
    }
}

Passo a passo

  1. Declaramos campos privados _largura e _altura para armazenar os valores.
  2. Criamos as propriedades Largura e Altura com get e init. O init valida se o valor é negativo e lança ArgumentException.
  3. A propriedade Area é calculada: public double Area => Largura * Altura;. Ela não tem campo de apoio; é recalculada a cada acesso.
  4. No Main, criamos r1 com valores válidos e exibimos r1.Area.
  5. Tentamos criar r2 com largura negativa dentro de um try. O init lança a exceção.
  6. O catch captura e exibe a mensagem.

Por que funciona

As propriedades Largura e Altura usam init para garantir que só sejam definidas na criação e que nunca sejam negativas. Area é uma propriedade calculada que deriva de outras propriedades, mantendo os dados consistentes e sem duplicação. Assim, o objeto é imutável após a construção e sempre válido.

Erros comuns

  • Usar set em vez de init: permitiria alterar valores depois, quebrando a imutabilidade.
  • Não validar no init: valores negativos seriam aceitos, gerando área negativa.
  • Tentar atribuir Area: r1.Area = 10; gera erro de compilação, pois Area é somente leitura.
  • Esquecer de capturar a exceção: o programa terminaria com erro não tratado.

Outra forma de resolver

Use um construtor com validação e propriedades get apenas:

public Retangulo(double largura, double altura) {
    if (largura < 0 || altura < 0) throw new ArgumentException(...);
    Largura = largura; Altura = altura;
}
public double Largura { get; }
public double Altura { get; }

Preferível quando a validação envolve múltiplos parâmetros.

Saída esperada

Área: 15
Erro: Largura não pode ser negativa