1
resposta

[Projeto] Faça como eu fiz: agenda com controle de contatos duplicados

class Contato
{
    public Contato(string nome, string telefone)
    {
        Nome = nome;
        Telefone = telefone;
    }

    public string Nome { get; private set; }
    public string Telefone { get; private set; }
}

class Agenda
{
    private readonly List<Contato> contatos = new();

    public Agenda(string proprietario)
    {
        Proprietario = proprietario;
    }

    public string Proprietario { get; private set; }

    public int QuantidadeContatos => contatos.Count;

    public bool AdicionarContato(Contato contato)
    {
        if (contatos.Any(c => c.Nome == contato.Nome))
        {
            Console.WriteLine("Contato com esse nome já está na agenda.");
            return false;
        }
        else
        {
            contatos.Add(contato);
        }

        return true;
    }

    public void ListarContatos()
    {
        Console.WriteLine($"Agenda de: {Proprietario}");
        Console.WriteLine("Contatos:");
        foreach (var item in contatos)
        {
            Console.WriteLine($"- {item.Nome} | {item.Telefone}");
        }
        Console.WriteLine($"Total de contatos: {QuantidadeContatos}");
    }
}

Agenda agenda = new Agenda("Marina Souza");
agenda.AdicionarContato(new Contato("Carlos", "11998887777"));
agenda.AdicionarContato(new Contato("Carlos", "11991112222")); // duplicado
agenda.AdicionarContato(new Contato("Julia", "21988776655"));
agenda.ListarContatos();
1 resposta

Olá, Eduardo. Como vai?

Parabéns por mais essa entrega excelente! Você aplicou um conceito fundamental na gestão de dados: a Integridade da Informação. Ao impedir que contatos com nomes duplicados sejam adicionados, você transformou sua classe em uma estrutura de dados inteligente, e não apenas em uma lista passiva.

Gostaria de destacar alguns pontos técnicos de alto nível no seu código:

  • Uso do LINQ: A utilização do método .Any() foi uma escolha muito acertada. É uma forma semântica e performática de verificar a existência de um elemento, tornando o código muito mais legível do que um laço foreach manual para busca.
  • **Encapsulamento com private readonly**: Ao marcar a lista de contatos como readonly, você garante que a instância da lista não seja acidentalmente substituída por outra dentro da classe, protegendo a referência do objeto.
  • Retorno Booleano: O método AdicionarContato retornar um bool é uma ótima prática de design de software. Isso permite que quem está usando a classe saiba se a operação teve sucesso ou não, permitindo tomar decisões baseadas nesse retorno.

Para levar seu aprendizado ainda mais longe, aqui vai uma dica sobre Normalização de Dados:

Atualmente, se você tentar adicionar "carlos" (com 'c' minúsculo), seu código permitirá a duplicata, pois o C# diferencia maiúsculas de minúsculas por padrão (case-sensitive). Para tornar sua agenda à prova de falhas, você pode ajustar a comparação para ignorar essas diferenças:

// Uma forma mais segura de evitar duplicados
if (contatos.Any(c => c.Nome.Equals(contato.Nome, StringComparison.OrdinalIgnoreCase)))
{
    // ... lógica de erro
}

Além disso, notei que você utilizou o target-typed new (new()), o que mostra que você está bem atualizado com as versões recentes do C#.

Sua trajetória nos cursos de Orientação a Objetos está impecável. Você está construindo classes robustas e que seguem bons princípios de design.

Espero que possa ter lhe ajudado!