C# - Trabalhando com Coleções Genéricas do tipo List(<T>)


 A coleção List(T) representa uma coleção de objetos tipados a qual é altamente otimizada oferecendo um bom desempenho e pode ser acessada usando índice.

Esta classe fornece métodos para percorrer, filtrar, ordenar, procurar e manipular coleções. ( A versão não génerica seria a classe ArrayList ).

A Classe List(<T>) representa uma lista de objetos que podem ser acessados pelo índice. Fornece métodos para pesquisar, ordenar e manipular listas.

A classe List(<T>) é o equivalente genérico da classe ArrayList. Ele implementa a interface genérica IList<(Of <(T>)>) usando uma matriz cujo tamanho é aumentado dinamicamente conforme necessário. O List(<T>) usa um comparador de igualdade e um comparador de classificação.

Obs: Métodos, como
Contains, IndexOf, LastIndexOf e Remove usam um comparador de igualdade para os elementos de lista e métodos, como BinarySearch e Sort usam um comparador de classificação para os elementos de lista.

É muito importante você conhecer e saber usar a classe List(<T>) e neste artigo eu procuro mostrar algumas operações básicas.

Eu vou usar o Visual C# 2008 Express Edition nos exemplos deste artigo:

Abra o Visual C# e crie um novo projeto do tipo Windows Application com o nome usandoColecoesTipadas;

No formulário padrão form1.cs inclua os controles : ListBox , GroupBox e Button conforme o leiaute abaixo:

A primeira coisa a fazer é criar um arquivo do tipo Class onde iremos definir a nossa classe de domínio. Clique no menu Project e selecione Add Class informando o nome Pessoa.cs e clicando em Add;

Para este exemplo eu vou definir uma classe Pessoa com os seguintes atributos:

using System;
using System.Collections.Generic;
using System.Text;

namespace usandoColecoesTipadas
{
    class Pessoa
    {
        public Pessoa()
        {}
 
        public Pessoa(int _id, string _nome, short _idade, char _sexo)
        {
            this.p_id    = _id;
            this.p_nome  = _nome;
            this.p_idade = _idade;
            this.p_sexo  = _sexo;
        }
 
        private int p_id = -1;
        private string p_nome = String.Empty;
        private short p_idade = 0;
        private char? p_sexo = null;
 
        public int ID
        { get{return p_id;}
          set{p_id = value;}}
 
        public string Nome
        { get{return p_nome;}
          set{p_nome = value;}}
 
        public short Idade
        {  get{return p_idade;}
           set{p_idade = value;} }
 
        public char? Sexo
        { get{return p_sexo;}
          set{p_sexo = value;}}
    }
}

Teremos que carregar a nossa coleção com dados pois vamos trabalhar com a coleção mostrando os recursos da classe List<T>; para isso no evento Load do formulário vamos incluir o código que irá preencher a nossa lista toda a vez que o mesmo for carregado:

Eu vou definir uma rotina chamada carregaLista() que será chamada no evento Load:

private void Form1_Load(object sender, EventArgs e)
{
     carregaLista();
}

O código da rotina carregaLista() é dado a seguir , nela estamos atribuindo valores para as propriedades id, nome, idade e sexo:

       private void carregaLista()
        {
            pLista = new List<Pessoa>();
            pLista.Add(new Pessoa(1, "João", 29, 'M'));
            pLista.Add(new Pessoa(2, "Macoratti", 35, 'F'));
            pLista.Add(new Pessoa(3, "Americo", 25, 'M'));
            pLista.Add(new Pessoa(4, "Katia", 21, 'F'));
            pLista.Add(new Pessoa(5, "Lena", 33, 'F'));
            pLista.Add(new Pessoa(6, "Suzana", 45, 'F'));
            pLista.Add(new Pessoa(7, "Jim", 38, 'M'));
            pLista.Add(new Pessoa(8, "Jane", 32, 'F'));
            pLista.Add(new Pessoa(9, "Roberto", 31, 'M'));
            pLista.Add(new Pessoa(10, "Cintia", 25, 'F'));
            pLista.Add(new Pessoa(11, "Gina", 27, 'F'));
            pLista.Add(new Pessoa(12, "Joel", 33, 'M'));
            pLista.Add(new Pessoa(13, "Germano", 55, 'M'));
            pLista.Add(new Pessoa(14, "Ricardo", 22, 'M'));
            pLista.Add(new Pessoa(15, "Maria", 39, 'F'));
        }

Para imprimir o resultado das operações eu vou criar uma rotina no formulário chamada Imprimir() onde eu vou passar como parâmetro a lista que eu quero imprimir e uma informação que será exibida no ListBox:

      void Imprimir(List<Pessoa> pLista, string info)
        {
            //limpa o controle ListBox 
            lstResultado.Items.Clear();
           //'exibe a informação no controle, uma linha em branco e em seguida o cabeçalho
            lstResultado.Items.Add(info);
            lstResultado.Items.Add("");
            lstResultado.Items.Add("ID\tNome\tIdade\tSexo");
            //Percorre a lista e exibe os dados da mesma
            pLista.ForEach(delegate(Pessoa p)
            {
                lstResultado.Items.Add(p.ID+ "\t"+ p.Nome+"\t"+ p.Idade + "\t" + p.Sexo);}
            );
        }

Obs: Os caracteres \t representam a tabulação (vbTab) e foram usados para formatar a saída na tela.

Os namespaces usados no formulário são:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

No início da definição do formulário temos que declarar uma variável do tipo List<Pessoa> onde Pessoa é a nossa classe, de forma que ela seja visível em todo o formulário:

List<Pessoa> pLista = null;

Agora estamos prontos para realizar as operações com a nossa lista tipada usando os recursos da classe List<T> com C#. Vamos lá...

1- Percorrendo e exibindo todos os itens da lista

      private void button1_Click(object sender, EventArgs e)
        {
            carregaLista();
            Imprimir(pLista, "Lista ordenada por ID");
        }

2- Filtrando informações da lista usando um critério

   private void button2_Click(object sender, EventArgs e)
        {
            List<Pessoa> listaFiltroPorIdade = pLista.FindAll(delegate(Pessoa p) { return p.Idade > 30; });
            Imprimir(listaFiltroPorIdade, "Pessoas com idades maiore que 30.");
        }

3- Ordenando a lista por um critério

    private void button3_Click(object sender, EventArgs e)
        {
            List<Pessoa> ordenaListaPorNome = pLista;
            ordenaListaPorNome.Sort(delegate(Pessoa p1, Pessoa p2)
            {
                return p1.Nome.CompareTo(p2.Nome);
            });
            Imprimir(ordenaListaPorNome, "Lista ordenada por Nome");
        }

Obs: Outra forma de ordenar a lista seria usar  LINQ:           
var listaOrdenada = from p in pLista orderby p.Nome select p;

4- Removendo itens da lista

    private void button5_Click(object sender, EventArgs e)
        {
            List<Pessoa> removerLista = pLista;
            removerLista.RemoveAll(delegate(Pessoa p) { return p.Sexo == 'M'; });
            Imprimir(removerLista, "Removendo da lista pessoas do sexo masculino");
        }

5- Localizando um item na lista

    private void button6_Click(object sender, EventArgs e)
        {
            //localiza um objeto
            Pessoa pessoa = pLista.Find(delegate(Pessoa p1) { return p1.ID == 10; });
            
            lstResultado.Items.Add("Pessoa localizada na lista com ID = 10");
            lstResultado.Items.Add(pessoa.ID+ "\t"+ pessoa.Nome+"\t"+ pessoa.Idade + "\t" + pessoa.Sexo);}
        }

As listas genéricas do tipo List<T> permitem realizar diversas operações com um bom desempenho e um código enxuto. Vale a pena se aprofundar no seu conhecimento.

Eu sei é apenas C#, mas eu gosto.

Pegue o projeto completo aqui : usandoColecoesTipadas.zip

Aguarde mais artigos sobre C#.

Referências:


José Carlos Macoratti