Fala ai Radizeiros e Radizeiras, tudo bem com vocês?
Estamos agora com mais uma nova série, iremos estar aqui no blog falando sobre generics em Delphi.
A grande maioria dos desenvolvedores têm dificuldade, não conhece, ou se conhece nunca usou, esse recurso,simplesmente por não saber onde encaixar e como usar.
Por isso vou trazer para vocês, muito conteúdo sobre generics, que vai desde a forma mais simples de usar os generics, até a forma mais complexa, com isso você vai aprender todos os recursos, para saber aproveitar tudo, dentro dos generics.
Nesse nosso primeiro post, iremos ver como criar uma classe que recebe um atributo genérico, e como fazer para utilizar esse atributo genérico.
Então vamos para o código?
Com um projeto simples de VCL, iremos colocar um botão no formulário, e iremos criar uma classe que recebe um generic.
Lembrando que todas as vezes que criamos um formulário no Delphi, ele já é uma classe.
TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
Vamos criar uma classe na unit do formulário mesmo.
TKeyValue = class end;
Essa é uma notação comum, que é utilizada para criar uma classe.
Quando queremos criar uma classe genérica, o que fazemos? Utilizamos os sinais maior que “>” e menor que “<”, e passamos para ele um atributo genérico, que por padrão é “T”, e estamos dizendo que essa classe está esperando para receber um tipo, e esse tipo nós não sabemos o que é.
Eu irei criar esse tipo em tempo de desenvolvimento, onde iremos passar esse tipo para essa classe.
TKeyValue<T> = class end;
Essa classe irá receber duas property, que será um Key e outra Value.
TKeyValue<T> = class property Key : String; property Value : T; end;
Observe que uma de nossas property está recebendo como tipo o “T”, ai que está o grande segredo da utilização dos generics, pois estou criando um tipo na minha classe que não sei o que ele é, pois ele pode ser qualquer tipo, ele pode ser uma outra classe, pode ser uma String, um inteiro, ele pode ser qualquer tipo.
Eu irei informar para ele no momento que eu for instanciar essa classe.
Vamos utilizar essa classe dando um Ctrl+Shift+C, para criar as propertys.
TKeyValue<T> = class private FKey: String; FValue: T; procedure SetKey(const Value: String); procedure SetValue(const Value: T); published property Key : String read FKey write SetKey; property Value : T read FValue write SetValue; end; implementation { TKeyValue<T> } procedure TKeyValue<T>.SetKey(const Value: String); begin FKey := Value; end; procedure TKeyValue<T>.SetValue(const Value: T); begin FValue := Value; end;
Agora, naquele botão que colocamos no formulário, iremos trabalhar com essa classe.
procedure TForm1.Button1Click(Sender: TObject); var KV : TKeyValue<TForm>; begin kV := TKeyValue<TForm>.Create; try KV.Key := 'F1'; KV.Value := Self; ShowMessage(KV.Key + ' - ' + KV.Value.Name); finally KV.Free; end; end;
Observe que criamos uma variável do tipo dessa nossa classe, e essa nossa classe recebeu como tipo, lembrando que ela poderia receber qualquer tipo, um TObject, mas também pode receber um TForm, e foi o que fizemos no código acima, passamos para o tipo genérico um TForm, e você pode observar que logo ele já herda as propriedades de TForm.
Executando o projeto e clicando no botão, veja a mensagem que foi mostrada no ShowMessage;
Mostrou o Key, que definimos como F1, e o value mostrou o nome do nosso formulário.
Viu como trabalhar com generics é muito legal?
Mas vamos dizer que eu não quero trabalhar com o TForm no tipo genérico dessa minha classe, e gostaria de que o tipo dessa classe fosse um TButton, e temos que fazer uma pequenas alterações no código, onde devemos alterar claro o tipo do genérico que está sendo criado, e em KV.Value, devemos alterar para um Sender, pois como estamos trabalhando com um TButton e ele está dentro de um botão passamos essa instância para ele, pois Self está se referindo ao formulário e de se deixarmos irá resultar em erro.
procedure TForm1.Button1Click(Sender: TObject); var KV : TKeyValue<TButton>; begin kV := TKeyValue<TButton>.Create; try KV.Key := 'F1'; KV.Value := Sender as TButton; ShowMessage(KV.Key + ' - ' + KV.Value.Name); finally KV.Free; end; end;
Viu como o código ficou?
Vamos compilar novamente nosso projetinho e executar para ver como a mensagem sai.
Viu que mudou o value?
O TButton também possui a propriedade Name, e com isso foi mostrado o valor que encontra-se nesta propriedade.
Viu como é muito legal trabalhar com generics, e isso é muito e muito útil quando você vai se aprofundando o seu nível de programação.
Mas você pode está se perguntando, beleza, você trabalhou com TForm e com TButton, mas se eu quiser criar uma lista, ou uma classe que tenha uma lista de números inteiros?
Sem problema nenhum, basta alterar o tipo genérico da classe para um tipo inteiro que a partir desse momento, ele receberá valores inteiro.
Se tentarmos executar o código anterior iremos resulta em erro, pois implementamos para um outro tipo que não é um inteiro, e se você verificar um tipo inteiro não possui uma propriedade Name, mas outras propriedades.
Simplesmente devemos alterar o código deixando dessa forma.
procedure TForm1.Button1Click(Sender: TObject); var KV : TKeyValue<Integer>; begin kV := TKeyValue<Integer>.Create; try KV.Key := 'F1'; KV.Value := 100; ShowMessage(KV.Key + ' - ' + KV.Value.ToString); finally KV.Free; end; end;
Vamos rodar novamente esse projeto?
Agora a minha mesma classe ta recebendo um inteiro e trabalhando com ela.
Tá vendo como generics é muito legal?
Eu não precisei alterar minha classe, eu só criei uma classe que irá receber qualquer valor, e acessar as propriedade de qualquer valor dela, e sem precisar voltar na classe e ter que desenvolver uma classe para cada ação, podendo simplesmente uma única classe você consegue receber esses parâmetros de forma genérica e trabalhar com ele.
Essa é apenas uma introdução sobre generics, mas iremos seguir essa série, onde até o final desta série iremos ter posts sobre generics, e vamos cada vez mais nos aprofundando nesses conhecimentos sobre generics, até você ser um expert sobre generics.
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
CLIQUE AQUI E SAIBA MAIS SOBRE O CLUBE DOS PROGRAMADORES DELPHI