2011-12-30 5 views
6

Chcę wymienić wszystkie właściwości: prywatne, chronione, publiczne itp. Chcę korzystać z wbudowanych urządzeń i nie używać żadnego kodu strony trzeciej.Jak wyliczyć wszystkie właściwości w obiekcie i uzyskać ich wartości?

+0

Z którą wersją Delphi pracujesz? Rozszerzony interfejs RTTI jest dostępny tylko od Delphi 2010. Starsze wersje nie będą w stanie tego osiągnąć: można wyświetlić tylko opublikowane właściwości. –

+1

Pytasz o uzyskanie wartości wszystkich właściwości. Nowy RTTI, dostępny w Delphi XE2, jest w stanie to zrobić. Link, który zamieściłem jako duplikat, był ogólnym odniesieniem do używania RTTI. Nie było żadnego wskazania na wersję Delphi, z której korzystałeś. Od czasu edycji pytania usunąłem mój duplikat. –

+1

@DavidHeffernan, Dzięki za miłą modyfikację moich pytań. – VibeeshanRC

Odpowiedz

5

użycie Rozszerzony RTTI tak (gdy testowałem kod w XE dostałem wyjątek od nieruchomości ComObject, więc dodaje TRY - z wyjątkiem bloku):

uses RTTI; 
procedure TForm1.Button1Click(Sender: TObject); 
var 
    C: TRttiContext; 
    T: TRttiType; 
    F: TRttiField; 
    P: TRttiProperty; 

    S: string; 

begin 
    T:= C.GetType(TButton); 
    Memo1.Lines.Add('---- Fields -----'); 
    for F in T.GetFields do begin 
    S:= F.ToString + ' : ' + F.GetValue(Button1).ToString; 
    Memo1.Lines.Add(S); 
    end; 

    Memo1.Lines.Add('---- Properties -----'); 
    for P in T.GetProperties do begin 
    try 
     S:= P.ToString; 
     S:= S + ' : ' + P.GetValue(Button1).ToString; 
     Memo1.Lines.Add(S); 
    except 
     ShowMessage(S); 
    end; 
    end; 
end; 
7

odpowiedź serg jest dobra, ale lepiej jest unikać wyjątki omijając pewne typy:

uses 
    Rtti, TypInfo; 

procedure TForm4.GetObjectProperties(AObject: TObject; AList: TStrings); 
var 
    ctx: TRttiContext; 
    rType: TRttiType; 
    rProp: TRttiProperty; 
    AValue: TValue; 
    sVal: string; 
const 
    SKIP_PROP_TYPES = [tkUnknown, tkInterface]; 
begin 
    if not Assigned(AObject) and not Assigned(AList) then 
    Exit; 

    ctx := TRttiContext.Create; 
    rType := ctx.GetType(AObject.ClassInfo); 
    for rProp in rType.GetProperties do 
    begin 
    if (rProp.IsReadable) and not (rProp.PropertyType.TypeKind in SKIP_PROP_TYPES) then 
    begin 
     AValue := rProp.GetValue(AObject); 
     if AValue.IsEmpty then 
     begin 
     sVal := 'nil'; 
     end 
     else 
     begin 
     if AValue.Kind in [tkUString, tkString, tkWString, tkChar, tkWChar] then 
      sVal := QuotedStr(AValue.ToString) 
     else 
      sVal := AValue.ToString; 
     end; 

     AList.Add(rProp.Name + '=' + sVal); 
    end; 

    end; 
end; 
2

Oto doskonały punkt wyjścia przy użyciu zaawansowanych możliwości najnowszej wersji Delphi:

Poniższy link jest kierowany raczej na wczesną wersję (z D5 na). W oparciu o TypInfo.pas jednostkowych, jest ograniczony, ale wciąż pouczający: