【问题标题】:How do I enumerate all properties in an object and obtain their values?如何枚举对象中的所有属性并获取它们的值?
【发布时间】:2011-12-30 13:07:21
【问题描述】:

我想枚举所有属性:私有、受保护、公共等。我希望使用内置设施而不使用任何第三方代码。

【问题讨论】:

  • 您使用的是哪个版本的 Delphi?增强型 RTTI 仅在 Delphi 2010 之后可用。旧版本无法实现这一点:只能列出已发布的属性。
  • 您正在询问获取所有属性的值。 Delphi XE2 中提供的新 RTTI 能够做到这一点。一般来说,我发布的重复链接是关于使用 RTTI 的一些参考。没有迹象表明您使用的是 Delphi 版本。由于您编辑了您的问题,我删除了我的重复项。
  • @DavidHeffernan ,感谢您很好地修改了我的问题。
  • 基本问题当然是“为什么?!?”

标签: delphi delphi-xe2


【解决方案1】:

Serg 的回答很好,但最好通过跳过某些类型来避免异常:

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】:

    像这样使用扩展 RTTI(当我在 XE 中测试代码时,我在 ComObject 属性上遇到异常,所以我插入了 try - except 块):

    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;
    

    【讨论】:

      【解决方案3】:

      这是使用最新 Delphi 版本的高级功能的绝佳起点:

      以下链接主要针对早期版本(从 D5 开始)。基于单位 TypInfo.pas,它是有限的但仍然具有指导意义:

      【讨论】:

        猜你喜欢
        • 2011-11-06
        • 1970-01-01
        • 1970-01-01
        • 2020-12-31
        • 2010-12-20
        • 2017-06-04
        相关资源
        最近更新 更多