Delphi 如何枚举对象中的所有属性并获取其值?

Delphi 如何枚举对象中的所有属性并获取其值?,delphi,delphi-xe2,Delphi,Delphi Xe2,我想枚举所有属性:private、protected、public等。我希望使用内置设施,而不使用任何第三方代码。像这样使用扩展RTTI(当我在XE中测试代码时,我在ComObject属性上遇到异常,所以我插入了try-except块): Serg的答案很好,但最好通过跳过某些类型来避免异常: uses Rtti, TypInfo; procedure TForm4.GetObjectProperties(AObject: TObject; AList: TStrings); var

我想枚举所有属性:private、protected、public等。我希望使用内置设施,而不使用任何第三方代码。

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


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;

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

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


您使用的是哪个版本的Delphi?增强型RTTI仅从Delphi 2010年起提供。旧版本将无法实现这一点:只能列出已发布的属性。您询问的是如何获取所有属性的值。Delphi XE2中提供的新RTTI能够做到这一点。我发布的重复链接通常是关于使用RTTI的一些参考。没有显示您正在使用的Delphi版本。因为你编辑了你的问题,我删除了我的副本。@DavidHeffernan,谢谢你很好地修改了我的问题。最重要的问题当然是“为什么?!”
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;