Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I enumerate all properties in an object and obtain their values?

I want to enumerate all properties: private, protected, public etc. I wish to use the built in facilities and not use any third party code.

like image 660
VibeeshanRC Avatar asked Dec 30 '11 13:12

VibeeshanRC


3 Answers

Serg's answer is good but it is better to avoid exceptions by skipping some types:

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;
like image 190
Linas Avatar answered Nov 11 '22 15:11

Linas


Use Extended RTTI like this (when I tested the code in XE I got exception on ComObject property, so I inserted try - except block):

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;
like image 36
kludg Avatar answered Nov 11 '22 16:11

kludg


Here is an excellent starting point using advanced capabilities of recent Delphi version:

  • Rtti Explorer Lite by RRUZ.

The following link rather targets early version (from D5 on). Based on the unit TypInfo.pas, it's limited but still instructive:

  • RTTI Explorer v.1.1 by Niek Sluyter.
like image 32
menjaraz Avatar answered Nov 11 '22 14:11

menjaraz