Por algum tempo fiquei pensando em uma solução para Class Helper ganhar poder de adicionar uma nova variável. Confesso que já estava desistindo, parecia não ser possível… mas – pensando bem….
Digamos que você tenha uma classe base que gostaria de fazer um Class Helper dela:
Exemplo de uma classe original:
[code]
TComponentX = class(TComponent)
public
published
end;
[/code]
(Code:A)
O desafio é como incluir uma nova variável a classe TComponentX utilizando de Class Helper…
Razões para usar um "Class Helper" e não uma herança:
se houver possibilidade de injetar a variável através de herança,
é provável que não irá precisar criar um "Class Helper"
- as razões para criar um "Class Helper"
é dispensar mudanças nos objetos em units já implementadas.
Agora, vamos usar o “Class Helper” para injetar uma nova variável à classe TComponentX:
[code]
TComponentHelper = Class Helper TComponent
public
Ligado:Boolean;
end;
[/code]
(Code:B)
Se estiver habituado ao uso de Class Helper, já deve ter notado que este exemplo (Code:B) não é compilado no Delphi – reclamando que um “Class Helper” não pode inserir uma nova variável. Não seja apressado, já lembrou que existe um “Class Var” e logo sugere escrever assim: ” class var Ligado:Boolean; “… Se este for o seu caso, não tenho boa notícia – você terá criado uma única referência para a variável, não podendo receber valores diferentes nas várias instâncias que a aplicação desejar manter carregada na memória – ou seja, criou uma simples variável GLOBAL que é compartilhada com todas as instâncias da classe;
No nosso caso, queremos que cada instância tenha o seu próprio valor, portanto não pode utilizar um “Class Var” como solução.
PROPOSTA:
[code]
unit Unit1;
interface
uses System.Classes, System.Generics.Collections;
type
TComponentHelper = Class Helper for TComponent
protected
function GetLigado: boolean;
procedure SetLigado(const AValue: boolean);
public
property Ligado: boolean Read GetLigado write SetLigado;
end;
implementation
var
LComponentLigado: TDictionary<TComponent, boolean>;
function TComponentHelper.GetLigado: boolean;
begin
result := true; // responde um padrão, para quando não existir;
if LComponentLigado.ContainsKey(self) then
result := LComponentLigado.Items[self]; // pega o valor da lista
end;
procedure TComponentHelper.SetLigado(const AValue: boolean);
begin
LComponentLigado.AddOrSetValue(self, AValue); // inclui na lista
end;
initialization
LComponentLigado := TDictionary<TComponent, boolean>.Create;
finalization
LComponentLigado.free;
end.
[/code]
A implementação permite adicionar novas variáveis ao objeto do “Class Helper” sem interferir no funcionamento da classe padrão.
…