Post: [Generics] Conhecendo os Generics

Alessandro Medeiros

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




Faça sua busca

CATEGORIAS

POSTS RECENTES

E caso você tem interesse de conhecer mais sobre [Generics] Conhecendo os Generics, acesse o nosso portal do CLUBE DE PROGRAMADORES EM DELPHI
Você não terá só conteúdos relacionados ao [Generics] Conhecendo os Generics, mas uma quantidade enorme de conteúdos que poderá lhe ajudar muito no seu dia a dia, é uma verdadeira NETFLIX para os programadores Delphi.
Gostou?
Compartilhe:

Embarque no foguete com milhares de devs para aprender desenvolvimento, evoluir de forma contínua e se manter relevante no mercado.

Dúvidas
Cadastre-se em nossa lista

Para ter acesso em primeira mão, a tudo que acontece na Academia do Código, basta se cadastrar em nossa lista

Grupo Thulio Bittencourt | Academia do Código

#FaçaPartedaHistória

Copyright © 2024 – Todos os direitos reservados