C# - Dica - Sobrescrevendo ToString()


 Hoje veremos uma dica bem simples sobre a sobrescrita do método ToString().

O método ToString é um método Virtual do tipo object e retorna uma representação de string.

O método ToString retorna por padrão o nome qualificado do tipo.

Como cada tipo herda de object, praticamente todos os objetos podem sobrescrever o método ToString.

Mas quando isso vale a pena ?

Bem, vai depender muito da situação, mas hoje veremos um caso onde sobrescrever o método ToString() em um tipo vale a pena.

Suponha que temos uma aplicação Windows Forms onde estamos tratando com informações de clientes.

Temos assim uma classe Cliente com o seguinte código:

    public class Cliente
    {
        public int Id { get; set; }
        public string Nome { get; set; }
        public string Endereco { get; set; }
        public string Telefone { get; set; }
        public string Email { get; set; }       
    }

Temos também uma classe chamada ClienteService que vamos usar para fornecer uma lista de clientes:

    public class ClientesService
    {
        public static List<Cliente> GetClientes()
        {
            var listaClientes = new List<Cliente>()
            {
                new Cliente { Id=1, Nome="Macoratti", Endereco="Rua Projetada, 100", Email= "macoratti@yahoo.com", Telefone="11-9985-2311"},
                new Cliente { Id=2, Nome="Miriam", Endereco="Rua Equador, 34", Email= "mimi@hotmail.com", Telefone="21-8875-0011"},
            };
            return listaClientes;
        }
    }

Exibindo Clientes

Na nossa aplicação temos um formulário onde vamos exibir uma lista de clientes em um controle ListBox.

No controle listbox vamos exibir apenas os nomes dos clientes e quando selecionarmos um cliente da lista os detalhes do cliente deverão ser exibidos em controles TextBox no formulário. Abaixo temos a figura que representa esse funcionamento:

Vejamos como implementar essa funcionalidade...

Primeiro vamos exibir os clientes. Para isso vamos definir no construtor do formulário uma chamada ao método ExibirClientes() que tem o seguinte  código:

       private void ExibirClientes()
       {
            lbClientes.Items.Clear();
            var clientes = ClientesService.GetClientes();
            foreach (var cliente in clientes)
                 lbClientes.Items.Add(cliente.Nome);
        }

Temos aqui um código bem simples que limpa a ListBox e a seguir obtém a lista de clientes e percorre a lista exibindo o nome do cliente na ListBox.

Executando o projeto iremos obter:

Vemos os nomes dos clientes exibidos na listbox. Agora precisamos selecionar um cliente e exibir os detalhes nos controles TextBox.

Exibindo detalhes do cliente

Para isso podemos usar o evento SelectedIndexChanged e verificar quando um cliente foi selecionado. Neste caso faremos o seguinte:

- Obtemos o cliente selecionado usando o método SelectedItem que retorna um item atual selecionado no listbox e armazenamos em uma variável
- A seguir exibirmos esse item nos controles TextBox

O código a implementar seria o seguinte:

        private void lbClientes_SelectedIndexChanged(object sender, EventArgs e)
        {
            var clienteSelecionado = (Cliente)lbClientes.SelectedItem;
            txtID.Text = clienteSelecionado.Id.ToString();
            txtNome.Text = clienteSelecionado.Nome;
            txtEndereco.Text = clienteSelecionado.Endereco;
            txtTelefone.Text = clienteSelecionado.Telefone;
            txtEmail.Text = clienteSelecionado.Email;
        }

Observe que estamos dando um cast no item selecionado para obter um objeto Cliente.

Se você executar o projeto e selecionar um item da lista vai obter o seguinte resultado:

O que esta acontecendo aqui ?

Ocorreu um erro do tipo InvalidCastException indicando que não foi possível converter um objeto do tipo System.String no tipo Cliente.

A explicação é bem simples.

Quando exibimos os clientes no ListBox usamos o seguinte código:

 lbClientes.Items.Add(cliente.Nome);

E assim estamos exibindo a propriedade Nome do objeto cliente que é do tipo String. Temos assim no listbox uma lista de strings e não de objetos Cliente.

E como resolver isso ???

Simples, sobrescrevendo o método ToString() na classe Cliente:

    public class Cliente
    {
        public int Id { get; set; }
        public string Nome { get; set; }
        public string Endereco { get; set; }
        public string Telefone { get; set; }
        public string Email { get; set; }       
        public override string ToString() => $"{Nome}".Trim();
    }

A seguir alteremos o código do método ExibirClientes() para exibir objetos Cliente e não a propriedade Nome do objeto Cliente:

       private void ExibirClientes()
       {
            lbClientes.Items.Clear();
            var clientes = ClientesService.GetClientes();
            foreach (var cliente in clientes)
                 lbClientes.Items.Add(cliente);
        }

Agora executando a aplicação, ao selecionar um item da ListBox vamos selecionar um objeto Cliente e exibir as propriedades nas caixas de texto TextBox:

Maravilha...

Parece simples, mas vale a pena sobrescrever o método ToString() na classe Cliente. Isto é um detalhe que faz toda a diferença...

E estamos conversados...

Pegue o projeto aqui :   WF_ClassControl.zip

"Jesus lhes respondeu, e disse: A minha doutrina não é minha, mas daquele que me enviou.
Se alguém quiser fazer a vontade dele, pela mesma doutrina conhecerá se ela é de Deus, ou se eu falo de mim mesmo."
João 7:16,17


José Carlos Macoratti