1
resposta

[Resolução] Faça como eu fiz: validação de nota mínima

OBS: Está um pouco diferente do solicitado, mas aplica tudo o que foi pedido, porém algumas coisas estão em lugares diferentes, como por exemplo o fato de não ter um método para atribuir a nota para a avaliação, pois fiz as validações no próprio construtor(Claro que nesse caso ,eu poderia ter mantido o método, e ter chamado ele no construtor passando os parâmetros pra ele. Mas validando dentro do construtor o objeto não chega a ser criado em caso de erro).

Aluno.cs

using System.Text;

namespace E02ValidacaoDeNotaMinima.Models;


internal class Aluno(int matricula, string nome, DateTime dataNascimento)
{
    private List<Avaliacao> _avaliacoes = [];
    public int Matricula { get; } = matricula;
    public string Nome { get; } = nome;
    public int Idade
    {
        get
        {
            var dataDeHoje = DateTime.Today;
            int anos = dataDeHoje.Year - DataNascimento.Year;
            if (dataDeHoje.AddYears(-anos) < DataNascimento)
                anos--;
            return anos;
        }
    }
    public DateTime DataNascimento { get; } = dataNascimento;
    public double Media => _avaliacoes.Sum(x => x.Peso) == 0
        ? 0
        : _avaliacoes.Sum(x => x.Nota * x.Peso) / _avaliacoes.Sum(x => x.Peso);

    public void AtribuirAvaliacao(Avaliacao avaliacao)
    {
        _avaliacoes.Add(avaliacao);
        Console.WriteLine($"Avaliação com nota {avaliacao.Nota} e peso {avaliacao.Peso} atribuida com sucesso!");
    }

    public override string ToString()
    {
        StringBuilder sb = new();

        sb.AppendLine($"\nDetalhes do aluno");
        sb.AppendLine($"-------------------------------");
        sb.AppendLine($"Nome: {Nome}");
        sb.AppendLine($"Idade: {Idade}");
        sb.AppendLine($"Data de nascimento: {DataNascimento:dd/MM/yyyy}");
        sb.AppendLine($"Média: {Media:f1}");
        sb.AppendLine($"Status: {(Media >= 7 ? "APROVADO" : "REPROVADO")}");
        sb.AppendLine($"-------------------------------");
        sb.AppendLine($"Avaliações realizadas: {_avaliacoes.Count}");
        return sb.ToString();
    }
}

Avaliacao.cs

namespace E02ValidacaoDeNotaMinima.Models;

internal class Avaliacao
{
    public Avaliacao(double nota, double peso)
    {
        if (nota < 0 || nota > 10) throw new ArgumentOutOfRangeException(nameof(nota), "A nota deve ser um valor entre 0 e 10.");
        if (peso < 0) throw new ArgumentOutOfRangeException(nameof(peso), "O peso não pode ser negativo.");

        Nota = nota;
        Peso = peso;
    }
    public double Nota { get; private set; }
    public double Peso { get; private set; }

}

AvaliacaoNaoProcessada.cs é uma classe que representa os dados que possivelmete(desde que atendam as regras de negocio), serão as avaliações de um aluno.

namespace E02ValidacaoDeNotaMinima.Models;

internal record AvaliacaoNaoProcessada(double Nota, double Peso);

Program.cs

using E02ValidacaoDeNotaMinima.Models;

List<AvaliacaoNaoProcessada> avaliacoesNaoProcessadas =
[
    new(11,5),  // inválido -> nota maior que o limite permitido
    new(8,-5),  // inválido -> peso negativo
    new(10,4),  // válido
    new(8,5),   // válido
    new(5,6)    // válido
];

Aluno aluno = new(123456789, "Carla Silva", new(2010, 07, 21));

foreach (var avaliacaoNaoProcessada in avaliacoesNaoProcessadas)
{
    try
    {
        Avaliacao novaAvaliação = new(
        avaliacaoNaoProcessada.Nota,
        avaliacaoNaoProcessada.Peso);

        aluno.AtribuirAvaliacao(novaAvaliação);
    }
    catch (ArgumentOutOfRangeException ex)
    {
        Console.WriteLine($"Erro no parâmetro ({ex.ParamName}) - {ex.Message}");
    }
}

Console.WriteLine(aluno);
1 resposta

Olá, Gerson! Como vai?

Parabéns pela resolução da atividade!

Observei que você explorou o uso de construtores para validação de dados em C#, utilizou muito bem o encapsulamento para proteger os atributos e ainda compreendeu a importância da sobrescrita de métodos para apresentar informações de forma organizada.

Uma dica interessante para o futuro é separar a lógica de validação em métodos auxiliares, o que pode deixar o código mais reutilizável e fácil de manter. Assim:

internal class Avaliacao
{
    public Avaliacao(double nota, double peso)
    {
        ValidarNota(nota);
        ValidarPeso(peso);

        Nota = nota;
        Peso = peso;
    }

    private void ValidarNota(double nota)
    {
        if (nota < 0 || nota > 10)
            throw new ArgumentOutOfRangeException(nameof(nota), "A nota deve ser um valor entre 0 e 10.");
    }

    private void ValidarPeso(double peso)
    {
        if (peso < 0)
            throw new ArgumentOutOfRangeException(nameof(peso), "O peso não pode ser negativo.");
    }

    public double Nota { get; private set; }
    public double Peso { get; private set; }
}

Isso facilita futuras alterações nas regras de negócio sem precisar modificar diretamente o construtor.

Fico à disposição! E se precisar, conte sempre com o apoio do fórum.

Abraço e bons estudos!

AluraConte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!