GARANTIR DESCONTO

Fórum Custom Attributes com Enum no Delphi Xe2 #444759

04/06/2013

0

eu criei uma classe que herda de TCustomAttribute, no intuito de colocar dado a mais nos meus enumeradores e poder recupera depois

type
  TEnumAttribute = class (TCustomAttribute)
  private
    FCaption : string;
  public
    constructor Create (const Caption : string);
    property Caption : string read FCaption write FCaption;
  end;


que ficariam assim;


  [TEnumAttribute('CARTAO CREDITO')]
  [TEnumAttribute('CARTAO DEBITO')]
  TTiposCartoes = (tcCredito, tcDebito);




Alguem tem algum noção como eu poderia fazer para recuperar estes Atributos depois?

por exemplo:


tipoCartao: TTipoCartoes

tipoCartao := tcCredito

recuperarNome(tipoCartao) = 'CARTAO CREDITO';


Rafael Reis

Rafael Reis

Responder

Posts

04/06/2013

Diego Garcia

Olha, acho que não vai rolar usar RTTI com Enumerations... se você migrar seu projeto para o X3 ou superior você pode fazer um ClassHelper para isso, fica bem melhor...

Tentei fazer algo do tipo:

function TForm1.GetCaptionCartao(ATipoCartao : TTiposCartoes): string;
var
  _ctx: TRttiContext;
  _typ: TRttiType;
  ALista : TStringList;
  _ca: TCustomAttribute;
begin
  Result := 'Tipo não encontrado';
  ALista := TStringList.Create;
  _ctx := TRttiContext.Create;
  try
    _typ := _ctx.GetType(TTiposCartoes);
    if Assigned(_typ) then
    begin
      for _ca in _typ.GetAttributes do
      begin
        if _ca is TEnumAttribute then
          ALista.Add(TEnumAttribute(_ca).Caption);
      end;
      Result := ALista.Strings[ord(ATipoCartao)];
    end;
  finally
    _ctx.Free;
    ALista.Free;
  end;
end;


mas ocorre erro na linha
_typ := _ctx.GetType(TTiposCartoes);


Responder

Gostei + 0

04/06/2013

Diego Garcia

opa, distração minha. Consegui, espero que lhe ajude:

  TEnumAttribute = class(TCustomAttribute)
  private
    FCaption: string;
  public
    constructor Create(ACaption : String);
    property Caption : string read FCaption;
  end;

  [TEnumAttribute('Cartão de crédito')]
  [TEnumAttribute('Cartão de débito')]
  TTiposCartoes = (tcCredito, tcDebito);

....


function TForm1.GetCaptionCartao(ATipoCartao : TTiposCartoes): string;
var
  _ctx: TRttiContext;
  _typ: TRttiType;
  ALista : TStringList;
  _ca: TCustomAttribute;
begin
  Result := 'Tipo não encontrado';
  ALista := TStringList.Create;
  _ctx := TRttiContext.Create;
  try
    _typ := _ctx.GetType(TypeInfo(TTiposCartoes));
    if Assigned(_typ) then
    begin
      for _ca in _typ.GetAttributes do
      begin
        if _ca is TEnumAttribute then
          ALista.Add(TEnumAttribute(_ca).Caption);
      end;
      Result := ALista.Strings[ord(ATipoCartao)];
    end;
  finally
    _ctx.Free;
    ALista.Free;
  end;
end;

....

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(GetCaptionCartao(TTiposCartoes.tcCredito));
  ShowMessage(GetCaptionCartao(TTiposCartoes.tcDebito));
end;
Responder

Gostei + 0

12/09/2013

Rafael Reis

Cara, esse exemplo seu não consigo pegar as informações? vc chegou de testar? acredito que o delphi nçao suporte custom attributes com enum
Responder

Gostei + 0

13/09/2013

Marco Salles

Cara, esse exemplo seu não consigo pegar as informações? vc chegou de testar? acredito que o delphi nçao suporte custom attributes com enum



Hummm., Rafael

Mas a definição de sua classe esta somente leitura

property Caption : string read FCaption;


defina como no inicio

property Caption : string read FCaption write FCaption;

e implemente

constructor TEnumAttribute.Create(ACaption: String);
begin
Caption:=ACaption;
end;


[]sds

Responder

Gostei + 0

13/09/2013

Diego Garcia

@Marco, por a propriedade ser somente leitura não tem problema, basta mudar o seu construtor para

constructor TEnumAttribute.Create(const ACaption: String);
begin
  Self.FCaption:=ACaption;
end;


Rafael, eu testei sim e funcionou perfeitamente, inclusive passei a usar em rotinas minhas.
Aonde você teve problemas?
Responder

Gostei + 0

13/09/2013

Marco Salles

@Marco, por a propriedade ser somente leitura não tem problema, basta mudar o seu construtor para

constructor TEnumAttribute.Create(const ACaption: String);
begin
  Self.FCaption:=ACaption;
end;


Rafael, eu testei sim e funcionou perfeitamente, inclusive passei a usar em rotinas minhas.
Aonde você teve problemas?



veja , neste caso vc esta utilizando a var FCaption e neste caso realmente não há problema de ser somente leitura
de fato as coisas ocorrem na mesma unidade onde vc terá a visibilidade desta variavel e não ha muito sentido de
uma atribuição a property Caption , fora deste escopo

O Rafael não deve ter conseguido por talvez não ter definido o Constructor da classe , cetando o valor da variavel FCaption

[]sds

Responder

Gostei + 0

14/09/2013

Marco Salles

Então Diego, acabei por generalizar esta função , para ser genérica , desaclopada e independente do Tipo Enumerado , para ser reaproveitada sem nehuma digitação extra

http://marcosalles.wordpress.com/2013/09/14/classe-generica-para-decorar-tipos-enumerados/

[]sds
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar