Fala ai Radizeiros e Radizeiras, tudo bem com vocês?
Chegamos ao 3º post, da nossa série, sobre generics aqui no blog, é um grande prazer poder compartilhar com você esses conteúdos, porque eu sei que pode mudar e melhorar muito o seu nível como programador.
Nesse post agora nós iremos ver na prática o uso de generics, vamos literalmente colocar a mão no código, já que até agora até agora nós só vimos os conceitos sobre generics.
Então, agora iremos criar um método genérico, para transformar um tipo enumerado em uma lista, usar um tipo enumerado para preencher uma lista.
Aí você se pergunta, qual tipo vai ser esse enumerado? Qualquer um, graças ao poder dos generics.
Vamos lá?
Já temos aqui um projeto VCL sem nada para começarmos a trabalhar.
Agora vamos começar a implementar dentro desse nosso projeto.
Primeira coisa que devemos fazer é criar um tipo enumerado, vamos usar esse enumerado para preencher uma lista, pode ser qualquer lista, desde um combo, memo, listview, qualquer um deles.
... TDias = (SEGUNDA, TERCA, QUARTA, QUINTA, SEXTA, SABADO, DOMINGO); TMes = (JANEIRO, FEVEREIRO, MARCO, ABRIL, MAIO, JUNHO, JULHO, AGOSTO, SETEMBRO, OUTUBRO, NOVEMBRO, DEZEMBRO); ...
Iremos transformar esse nosso enumerado em itens, por exemplo, de um combobox, um memo, etc…
Para isso vamos criar uma classe para utilidade de enumerado que irá receber um tipo genérico, claro que não podia faltar ele né…rsrs.
... TEnumUtils<T> = class class procedure EnumToList(Value : TStrings); end; ...
Observe que nessa nossa classe criando um método que tem como chamada um class antes dele, não se assuste, não é uma classe dentro da outra, quando nós criamos um método com esse atributo class, estou dizendo que eu posso utilizar esse método sem precisar instanciar, ou criar, essa classe, eu não preciso chamar um TEnumUtils.Create, para usar e depois destruir ela, é um método que pode ser acessado diretamente sem precisar construir a classe.
Esse método recebe uma lista que irá preencher.
Mas ele não tinha que receber o enumerado?
Vou lhe mostra o que iremos fazer.
TEnumUtils<T> = class class procedure EnumToList(Value : TStrings); end; ... { TEnumUtils<T> } class procedure TEnumUtils<T>.EnumToList(Value: TStrings); var Aux : String; I : Integer; Pos : Integer; begin Value.Clear; I := 0; repeat Aux := GetEnumName(TypeInfo(T), I); Pos := GetEnumValue(TypeInfo(T), Aux); if Pos <> -1 then Value.Add(Aux); inc(I); until Pos < 0 ; end;
Observe a implementação dentro do método que irá trabalhar a lista de enumerados.
A primeira coisa que fizemos foi pegar o value que vem por passagem de parâmetro do método, limpamos a lista, usamos uma estrutura pouco usado que é o repeat, quando você faz um while, é testado uma condição, e se essa condição for atendida ela entra no while, com o repeat é ao contrário, é feita a condição e somente no final que é testado, se no final atender a condição ele sai de dentro desse loop.
Dentro desse repeat fizemos toda essa interação de jogar tudo que está no enumerado para uma lista.
Usamos uma variável do tipo string, e pegamos o nome do enumerado, o GetEnumerado está esperando um TypeInfo, e precisamos passar a informação de um tipo, e por isso passamos para ele o tipo genérico, e logo em seguida esse método GetEnumerado pede um tipo inteiro, esse tipo é a posição do enumerado, mas como eu não sei qual é a posição, passei uma variável para ele, e como estou dentro do repeat e ele executa primeiro para depois testar, e como eu precisava de uma condição para poder parar o repeat, foi adicionado a verificação onde ele pega um nome para retornar uma posição, e é aí que entra o GetEnumValue, pois a cada interação é retornado o valor da posição do nome, e quando ele passar por uma valor que não é o que está dentro do enumerado ele retorna o valor como -1, então é aí que ele irá sair do repeat.
E como temos que tratar esses valores e adicionar na lista o que é de fato do enumerado, adicionei um if, pois quando é passado a posição do enumerado, e ele só tem 4 posições e ao passar ele cai na 5ª posição, ele retorna o valor o nome da própria unit, então não é isso que queremos, com o if pegamos somente os valores que estão dentro do enumerado.
Agora temos uma classe para converter qualquer enumerado para um lista.
Agora para as coisas ficarem mais bonitas, vamos colocar um combobox na tela, e iremos adicionar mais dois botões, um eu chamos de Mês e o outro de Dia.
Para adicionar os meses dentro do combo é bem simples, dentro do botão observe a implementação.
procedure TForm1.Button1Click(Sender: TObject); begin TEnumUtils<TMes>.EnumToList(ComboBox1.Items); end;
E para visualizar os dia é mais simples ainda, só passar o enumerado TDias, agora é só compilar e veja o resultado.
Temos uma classe genérica responsável por trabalhar e popular qualquer lista para nós, baseado em tipos enumerados.
Ao clicar no botão mês.
Agora no mesmo combo, clicando em dias.
Olha como fica fácil quando trabalhamos com genéricos, imagina se tivesse que criar um método para cada enumerado desses?
Esse treinamento irá lhe ensinar tudo sobre Generics no Delphi, lhe guiando pelos principais conceitos e recursos disponíveis sobre essa feature fantástica do Delphi, aprenda a criar códigos maleáveis, de fácil adaptação e mudanças para ter códigos de alta performance utilizando o que o Delphi tem de melhor