{"id":927,"date":"2024-12-09T06:00:00","date_gmt":"2024-12-09T09:00:00","guid":{"rendered":"https:\/\/adrianosantostreina.com.br\/blog\/?p=927"},"modified":"2024-12-16T08:17:09","modified_gmt":"2024-12-16T11:17:09","slug":"entendendo-generics-no-delphi","status":"publish","type":"post","link":"https:\/\/adrianosantostreina.com.br\/blog\/entendendo-generics-no-delphi\/","title":{"rendered":"Entendendo Generics no Delphi"},"content":{"rendered":"\n<p>Generics s\u00e3o um poderoso recurso introduzido no Delphi a partir da vers\u00e3o 2009, permitindo que desenvolvedores criem classes, m\u00e9todos e tipos parametrizados que promovem seguran\u00e7a de tipo e reutiliza\u00e7\u00e3o de c\u00f3digo. Esse paradigma \u00e9 amplamente utilizado em linguagens modernas e oferece uma alternativa robusta \u00e0 pr\u00e1tica de usar tipos universais como <code>TObject<\/code>, que podem resultar em verifica\u00e7\u00f5es manuais e erros em tempo de execu\u00e7\u00e3o.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Ao usar generics, o programador pode criar estruturas altamente flex\u00edveis e tipadas, sem sacrificar o desempenho ou a integridade do c\u00f3digo. Classes gen\u00e9ricas, por exemplo, permitem que tipos espec\u00edficos sejam definidos apenas no momento da utiliza\u00e7\u00e3o, tornando o c\u00f3digo mais leg\u00edvel, eficiente e seguro.<\/p>\n\n\n\n<p>Neste artigo, abordaremos o conceito de generics no Delphi, com exemplos pr\u00e1ticos de como criar e manipular listas gen\u00e9ricas e classes parametrizadas. Para ilustrar, desenvolveremos uma classe gen\u00e9rica que manipula listas de objetos, mostrando como trabalhar com elementos de forma segura e escal\u00e1vel.<\/p>\n\n\n\n<p>Vamos explorar como implementar generics no Delphi, seus benef\u00edcios e as melhores pr\u00e1ticas para evitar armadilhas comuns.<\/p>\n\n\n\n<p><strong>O que s\u00e3o Generics no Delphi?<\/strong><\/p>\n\n\n\n<p>Generics permitem que voc\u00ea declare classes, interfaces, m\u00e9todos e tipos parametrizados. Eles s\u00e3o definidos por placeholders para tipos que s\u00e3o concretizados em tempo de compila\u00e7\u00e3o.<\/p>\n\n\n\n<p>A sintaxe b\u00e1sica para definir uma classe gen\u00e9rica no Delphi \u00e9:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >type\n  TMinhaClasseGenerica&lt;T&gt; = class\n  private\n    FDado: T;\n  public\n    procedure SetDado(const Value: T);\n    function GetDado: T;\n  end;\n<\/pre><\/div>\n\n\n\n<p>Nesse exemplo, <code>T<\/code> \u00e9 um par\u00e2metro de tipo que pode ser substitu\u00eddo por qualquer tipo concreto, como <code>Integer<\/code>, <code>String<\/code>, ou at\u00e9 mesmo outra classe.<\/p>\n\n\n\n<h3 class=\"wp-block-heading has-medium-font-size\"><strong>Exemplo Pr\u00e1tico: Classe Gen\u00e9rica para Manipula\u00e7\u00e3o de Listas<\/strong><\/h3>\n\n\n\n<p>Criemos uma classe gen\u00e9rica que atua como uma lista para armazenar elementos de tipos variados. Essa classe incluir\u00e1 m\u00e9todos para adicionar, remover e listar os elementos.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >type\n  TListaGenerica&lt;T&gt; = class\n  private\n    FItens: TList&lt;T&gt;;\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    procedure Adicionar(const Item: T);\n    procedure Remover(const Item: T);\n    function ObterTodos: TArray&lt;T&gt;;\n  end;\n\n{ TListaGenerica }\n\nconstructor TListaGenerica&lt;T&gt;.Create;\nbegin\n  inherited;\n  FItens := TList&lt;T&gt;.Create;\nend;\n\ndestructor TListaGenerica&lt;T&gt;.Destroy;\nbegin\n  FItens.Free;\n  inherited;\nend;\n\nprocedure TListaGenerica&lt;T&gt;.Adicionar(const Item: T);\nbegin\n  FItens.Add(Item);\nend;\n\nprocedure TListaGenerica&lt;T&gt;.Remover(const Item: T);\nbegin\n  FItens.Remove(Item);\nend;\n\nfunction TListaGenerica&lt;T&gt;.ObterTodos: TArray&lt;T&gt;;\nbegin\n  Result := FItens.ToArray;\nend;\n<\/pre><\/div>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Como Usar a Classe Gen\u00e9rica<\/strong><\/h4>\n\n\n\n<p>A seguir, um exemplo de como usar essa classe gen\u00e9rica para manipular uma lista de strings:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >procedure TestarGenerics;\nvar\n  Lista: TListaGenerica&lt;String&gt;;\nbegin\n  Lista := TListaGenerica&lt;String&gt;.Create;\n  try\n    Lista.Adicionar('Delphi');\n    Lista.Adicionar('Generics');\n    Lista.Remover('Delphi');\n    \n    var Itens: TArray&lt;String&gt; := Lista.ObterTodos;\n    for var Item in Itens do\n      Writeln(Item);\n  finally\n    Lista.Free;\n  end;\nend;\n<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Benef\u00edcios do Uso de Generics<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Seguran\u00e7a de Tipo<\/strong>: Erros de tipos s\u00e3o detectados em tempo de compila\u00e7\u00e3o, reduzindo falhas em tempo de execu\u00e7\u00e3o.<\/li>\n\n\n\n<li><strong>Reutiliza\u00e7\u00e3o de C\u00f3digo<\/strong>: Classes e m\u00e9todos gen\u00e9ricos podem ser usados com qualquer tipo, eliminando a necessidade de duplicar l\u00f3gica.<\/li>\n\n\n\n<li><strong>Performance<\/strong>: Como a substitui\u00e7\u00e3o do tipo ocorre em tempo de compila\u00e7\u00e3o, n\u00e3o h\u00e1 impacto no desempenho em tempo de execu\u00e7\u00e3o.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Boas Pr\u00e1ticas<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sempre nomeie seus par\u00e2metros de tipo de maneira clara, como <code>T<\/code>, <code>TKey<\/code>, <code>TValue<\/code>, para melhorar a legibilidade.<\/li>\n\n\n\n<li>Evite a cria\u00e7\u00e3o de classes gen\u00e9ricas muito complexas, pois podem dificultar a manuten\u00e7\u00e3o do c\u00f3digo.<\/li>\n\n\n\n<li>Utilize m\u00e9todos e propriedades bem definidos para encapsular a l\u00f3gica.<\/li>\n<\/ul>\n\n\n\n<p class=\"has-medium-font-size\"><strong>Exemplo Pr\u00e1tico: Sistema de Emiss\u00e3o de Notas Fiscais Eletr\u00f4nicas<\/strong><\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Estrutura do Sistema<\/strong><\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Classe gen\u00e9rica para manipula\u00e7\u00e3o de listas de objetos relacionados \u00e0 nota fiscal.<\/li>\n\n\n\n<li>Classes espec\u00edficas para o cabe\u00e7alho e os itens da nota fiscal.<\/li>\n\n\n\n<li>Uso das classes gen\u00e9ricas para organizar os dados.<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Definindo as Classes<\/strong><\/h4>\n\n\n\n<p><strong>1. Classe TNotaFiscalCabecalho<\/strong><br>Representa o cabe\u00e7alho da nota fiscal, contendo informa\u00e7\u00f5es como n\u00famero, data e cliente.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><\/ol>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >type\n  TNotaFiscalCabecalho = class\n  private\n    FNumero: Integer;\n    FData: TDateTime;\n    FCliente: String;\n  public\n    property Numero: Integer read FNumero write FNumero;\n    property Data: TDateTime read FData write FData;\n    property Cliente: String read FCliente write FCliente;\n  end;\n<\/pre><\/div>\n\n\n\n<p><strong>2.<\/strong> <strong>Classe TNotaFiscalItem<\/strong><br>Representa os itens da nota fiscal, contendo descri\u00e7\u00e3o, quantidade e valor unit\u00e1rio.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >type\n  TNotaFiscalItem = class\n  private\n    FDescricao: String;\n    FQuantidade: Double;\n    FValorUnitario: Currency;\n  public\n    property Descricao: String read FDescricao write FDescricao;\n    property Quantidade: Double read FQuantidade write FQuantidade;\n    property ValorUnitario: Currency read FValorUnitario write FValorUnitario;\n    function ValorTotal: Currency;\n  end;\n\n{ TNotaFiscalItem }\n\nfunction TNotaFiscalItem.ValorTotal: Currency;\nbegin\n  Result := FQuantidade * FValorUnitario;\nend;\n<\/pre><\/div>\n\n\n\n<p>3. <strong>Classe Gen\u00e9rica TListaNotaFiscal<\/strong><br>Utilizada para manipular listas de cabe\u00e7alhos ou itens.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >type\n  TListaNotaFiscal&lt;T&gt; = class\n  private\n    FItens: TList&lt;T&gt;;\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    procedure Adicionar(const Item: T);\n    function ObterTodos: TArray&lt;T&gt;;\n  end;\n\n{ TListaNotaFiscal }\n\nconstructor TListaNotaFiscal&lt;T&gt;.Create;\nbegin\n  inherited;\n  FItens := TList&lt;T&gt;.Create;\nend;\n\ndestructor TListaNotaFiscal&lt;T&gt;.Destroy;\nbegin\n  FItens.Free;\n  inherited;\nend;\n\nprocedure TListaNotaFiscal&lt;T&gt;.Adicionar(const Item: T);\nbegin\n  FItens.Add(Item);\nend;\n\nfunction TListaNotaFiscal&lt;T&gt;.ObterTodos: TArray&lt;T&gt;;\nbegin\n  Result := FItens.ToArray;\nend;\n<\/pre><\/div>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Usando as Classes no Sistema de Emiss\u00e3o<\/strong><\/h4>\n\n\n\n<p>Exemplo de como criar um cabe\u00e7alho e adicionar itens \u00e0 nota fiscal:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >procedure EmitirNotaFiscal;\nvar\n  Cabecalho: TNotaFiscalCabecalho;\n  Item: TNotaFiscalItem;\n  ListaItens: TListaNotaFiscal&lt;TNotaFiscalItem&gt;;\nbegin\n  \/\/ Criando o cabe\u00e7alho da nota fiscal\n  Cabecalho := TNotaFiscalCabecalho.Create;\n  try\n    Cabecalho.Numero := 12345;\n    Cabecalho.Data := Now;\n    Cabecalho.Cliente := 'Cliente Exemplo';\n\n    \/\/ Criando a lista de itens\n    ListaItens := TListaNotaFiscal&lt;TNotaFiscalItem&gt;.Create;\n    try\n      \/\/ Adicionando itens \u00e0 nota fiscal\n      Item := TNotaFiscalItem.Create;\n      Item.Descricao := 'Produto A';\n      Item.Quantidade := 10;\n      Item.ValorUnitario := 50.00;\n      ListaItens.Adicionar(Item);\n\n      Item := TNotaFiscalItem.Create;\n      Item.Descricao := 'Produto B';\n      Item.Quantidade := 5;\n      Item.ValorUnitario := 100.00;\n      ListaItens.Adicionar(Item);\n\n      \/\/ Exibindo os itens\n      for Item in ListaItens.ObterTodos do\n        Writeln(Format('%s: %.2f x %.2f = %.2f', \n          [Item.Descricao, Item.Quantidade, Item.ValorUnitario, Item.ValorTotal]));\n    finally\n      ListaItens.Free;\n    end;\n  finally\n    Cabecalho.Free;\n  end;\nend;\n<\/pre><\/div>\n\n\n\n<p><strong>Sa\u00edda Esperada<\/strong><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >Produto A: 10.00 x 50.00 = 500.00  \nProduto B: 5.00 x 100.00 = 500.00  \n<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Benef\u00edcios do Uso de Generics no Exemplo<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Flexibilidade<\/strong>: A classe gen\u00e9rica <code>TListaNotaFiscal&lt;T><\/code> pode ser reutilizada tanto para o cabe\u00e7alho quanto para os itens.<\/li>\n\n\n\n<li><strong>Seguran\u00e7a de Tipo<\/strong>: Garante que somente objetos do tipo especificado sejam adicionados \u00e0 lista.<\/li>\n\n\n\n<li><strong>Manutenibilidade<\/strong>: Adicionar novos tipos relacionados \u00e0 nota fiscal ser\u00e1 mais simples e organizado.<\/li>\n<\/ol>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Participe da Comunidade no Telegram<\/h3>\n\n\n\n<p>\ud83d\ude80 Quer continuar essa discuss\u00e3o e trocar ideias com outros desenvolvedores? Junte-se \u00e0 nossa comunidade no Telegram! L\u00e1, voc\u00ea pode comentar sobre o que achou deste artigo, tirar suas d\u00favidas e compartilhar suas experi\u00eancias com Delphi e ainda discutir ou tirar suas d\u00favidas sobre os mais variados temas em uma comunidade com mais de 1.000 desenvolvedores.<\/p>\n\n\n\n<p>\ud83d\udd17 <a href=\"https:\/\/t.me\/AdrianoSantosCommunity\" target=\"_blank\" rel=\"noreferrer noopener\">Clique aqui para entrar na comunidade<\/a><\/p>\n\n\n\n<p>Te vejo l\u00e1!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Conclus\u00e3o<\/strong><\/h3>\n\n\n\n<p>Generics s\u00e3o uma ferramenta poderosa no Delphi, permitindo que desenvolvedores criem solu\u00e7\u00f5es mais flex\u00edveis, reutiliz\u00e1veis e seguras. No exemplo apresentado, vimos como utilizar generics para estruturar um sistema de emiss\u00e3o de notas fiscais, aplicando conceitos avan\u00e7ados para manipula\u00e7\u00e3o de dados de forma eficiente.<\/p>\n\n\n\n<p>A classe gen\u00e9rica <code>TListaNotaFiscal&lt;T&gt;<\/code> demonstrou como podemos criar listas tipadas, adapt\u00e1veis a diferentes tipos de dados, enquanto as classes <code>TNotaFiscalCabecalho<\/code> e <code>TNotaFiscalItem<\/code> mostraram como encapsular informa\u00e7\u00f5es relevantes em estruturas bem definidas.<\/p>\n\n\n\n<p>Ao usar generics, desenvolvedores podem reduzir duplica\u00e7\u00e3o de c\u00f3digo, aumentar a clareza e evitar erros comuns relacionados \u00e0 manipula\u00e7\u00e3o de tipos. Apesar de serem um recurso avan\u00e7ado, com pr\u00e1tica e aplica\u00e7\u00e3o cuidadosa, eles podem transformar a forma como projetos Delphi s\u00e3o desenvolvidos, especialmente em sistemas complexos e escal\u00e1veis.<\/p>\n\n\n\n<p>Se voc\u00ea deseja explorar mais sobre generics ou outros recursos avan\u00e7ados do Delphi, temas como <em>interfaces gen\u00e9ricas<\/em>, <em>constrangimentos de tipos<\/em> e <em>fun\u00e7\u00f5es an\u00f4nimas parametrizadas<\/em> s\u00e3o \u00f3timos pr\u00f3ximos passos.<\/p>\n\n\n\n<p>Adriano Santos<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Generics s\u00e3o um poderoso recurso introduzido no Delphi a partir da vers\u00e3o 2009, permitindo que desenvolvedores criem classes, m\u00e9todos e tipos parametrizados que promovem seguran\u00e7a de tipo e reutiliza\u00e7\u00e3o de c\u00f3digo. Esse paradigma \u00e9 amplamente utilizado em linguagens modernas e oferece uma alternativa robusta \u00e0 pr\u00e1tica de usar tipos universais como TObject, que podem resultar [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":933,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-927","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"_links":{"self":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/927","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/comments?post=927"}],"version-history":[{"count":5,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/927\/revisions"}],"predecessor-version":[{"id":932,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/927\/revisions\/932"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/media\/933"}],"wp:attachment":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/media?parent=927"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/categories?post=927"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/tags?post=927"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}