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

后端 未结 3 1727
醉酒成梦
醉酒成梦 2021-01-05 09:56

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.

相关标签:
3条回答
  • 2021-01-05 10:04

    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;
    
    0 讨论(0)
  • 2021-01-05 10:08

    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;
    
    0 讨论(0)
  • 2021-01-05 10:21

    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.
    0 讨论(0)
提交回复
热议问题