2015-03-28 10 views
5

Czy jest możliwe i jak utworzyć i dołączyć niestandardowy atrybut do pola w środowisku wykonawczym?Jak utworzyć i dołączyć atrybut niestandardowy do pola w środowisku wykonawczym w Delphi

uses 
    System.SysUtils, 
    System.Classes, 
    System.Rtti; 

type 
    MyAttribute = class(TCustomAttribute) 
    private 
    fCaption: string; 
    public 
    constructor Create(const aCaption: string); 
    property Caption: string read fCaption write fCaption; 
    end; 

    TFoo = class(TPersistent) 
    public 
    [MyAttribute('Title')] 
    Bar: string; 
    Other: string; 
    end; 

constructor MyAttribute.Create(const aCaption: string); 
begin 
    fCaption := aCaption; 
end; 

procedure CreateAttributes(Typ: TRttiType); 
var 
    Field: TRttiField; 
    MyAttr: MyAttribute; 
begin 
    for Field in Typ.GetFields do 
    begin 
     if Length(Field.GetAttributes) = 0 then 
     begin 
      MyAttr := MyAttribute.Create('Empty'); 
      // how to attach created attribute to Field ??? 
     end; 
    end; 
end; 

var 
    Context: TRttiContext; 
    Typ: TRttiType; 
    Field: TRttiField; 
    Attr: TCustomAttribute; 

begin 
    Context := TRttiContext.Create; 
    Typ := Context.GetType(TFoo); 

    CreateAttributes(Typ); 

    for Field in Typ.GetFields do 
    for Attr in Field.GetAttributes do 
     if Attr is MyAttribute then 
     writeln(Field.Name + ' ' + MyAttribute(Attr).Caption); 
    readln; 
    Context.Free; 
end. 

Running powyższy kod wyjściowy:

Bar Title 

Chciałbym wstrzyknąć MyAttribute o wartości Empty do pól, które nie mają go w czasie wykonywania produkcji następujące dane wyjściowe:

Bar Title 
Other Empty 

Odpowiedz

2

Struktura nie zapewnia mechanizmu dołączania atrybutów w czasie wykonywania. Każda próba takiego rozwiązania wymagałaby włamania do frameworka.

+0

Chociaż tak być może. To tylko dowodzi, że atrybuty nie są dużo lepiej dostosowane do serializacji niż opublikowana dyrektywa. –

+0

@Dalija dlaczego opcje serializacji różnią się w czasie wykonywania –

+0

Jednym z powodów jest zmiana serializacji klas poza Twoją kontrolą, jak w [serializacji JSON bez śmieci] (http://stackoverflow.com/questions/29276304/how-to-serialize -an-tlistt-to-json-without-garbage) –

0

Atrybuty to magia podczas kompilacji. W czasie wykonywania nie potrzebujesz takich rzeczy. Wystarczy utworzyć własny słownik, gdzie typ i członek (członek może być ustawiony jako łańcuch) jest kluczem, a lista atrybutów jest wartością. A jeśli chcesz sprawdzić atrybuty, wykonaj to na dwa sposoby - często iw słowniku.

+0

Dzięki, ale to nie rozwiązuje problemu, gdy masz klasę poza kontrolą (nie możesz zmienić jej w czasie kompilacji) i musisz wykonać operację opartą na atrybutach (ponownie poza twoją kontrolą) na nim. Spójrz na [serializację JSON bez śmieci] (http://stackoverflow.com/questions/29276304/how-to-serialize-an-tlistt-to-json-without-garbage), aby uzyskać więcej informacji o tym, o czym mówię. –

Powiązane problemy