delphi - 可以只循环类的声明属性吗?

标签 delphi rtti

扩展的 RTTI 具有 GetDeclaredProperties 函数,这正是我所需要的,但是如果我在多线程中使用扩展的 RTTI,我会遇到问题。

因此,我使用了 GetPropList,但这为我提供了所有属性的列表 - 不仅在当前类中发布(或明确声明)。

TBaseSettings = class(TPersistent)
published
    property Charset: string read FCharset write FCharset;
end;

TBasicSettings = class(TBaseSettings)
published
    property forums: Variant read fforums write fforums;
end;

TConcreteSettings = class(TBasicSettings)
published
    property forums; // <-- make it explicit visible: OK
    property prefix: Variant read fprefix write fprefix; // <-- OK
end;

我不想读取Charset属性。

我的第一个猜测是使用 https://stackoverflow.com/a/1565686 的修改版本检查继承,但实际上 forums 属性也是继承的。

也许这对于经典的 RTTI 来说是不可能的?我使用Delphi 2010。

最佳答案

如果您的代码以与调用 GetPropList 类似的方式调用 GetDeclaredPropList 很方便,请参见下文。

编辑:我已经在 Delphi 7 中重写了代码,我相信它也应该在 Delphi 2010 中工作(我手头没有)。

type
  PPropData = ^TPropData;

function AfterString(P: Pointer): Pointer;
begin
  Result := Pointer(NativeUInt(P) + (PByte(P)^ + 1));
end;

function GetPropData(TypeData: PTypeData): PPropData;
begin
  Result := AfterString(@TypeData^.UnitName);
end;

function NextPropInfo(PropInfo: PPropInfo): PPropInfo;
begin
  Result := AfterString(@PropInfo^.Name);
end;

procedure GetDeclaredPropInfos(TypeInfo: PTypeInfo; PropList: PPropList);
var
  TypeData: PTypeData;
  PropData: PPropData;
  PropInfo: PPropInfo;
  I: Integer;
begin
  TypeData := GetTypeData(TypeInfo);
  PropData := GetPropData(TypeData);
  FillChar(PropList^, Sizeof(PPropInfo) * PropData^.PropCount, 0);
  PropInfo := PPropInfo(@PropData^.PropList);
  for I := 0 to PropData^.PropCount - 1 do
  begin
    PropList^[I] := PropInfo;
    PropInfo := NextPropInfo(PropInfo);
  end;
end;

function GetDeclaredPropList(TypeInfo: PTypeInfo; out PropList: PPropList): Integer; overload;
begin
  Result := GetPropData(GetTypeData(TypeInfo))^.PropCount;
  if Result > 0 then
  begin
    GetMem(PropList, Result * SizeOf(Pointer));
    GetDeclaredPropInfos(TypeInfo, PropList);
  end;
end;

function GetDeclaredPropList(AObject: TObject; out PropList: PPropList): Integer; overload;
begin
  Result := GetDeclaredPropList(PTypeInfo(AObject.ClassInfo), PropList);
end;

// example usage:
var
  I, Count: Integer;
  PropList: PPropList;
  PropInfo: PPropInfo;
begin
  Count := GetDeclaredPropList(TypeInfo(TConcreteSettings), PropList);
  try
    for I := 0 to Count - 1 do
    begin
      PropInfo := PropList^[I];
      Writeln(PropInfo^.Name);
    end;
  finally
    FreeMem(PropList);
  end;
end.

关于delphi - 可以只循环类的声明属性吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34397112/

相关文章:

delphi - 在 D2010 中可以做类似 XE2 LiveBindings 的事情吗?

macos - Delphi - OSX - 如何扩展 NSWindowDelegate

delphi - 按名称设置属性值

德尔福: How to create a generic type programatically?

delphi - TPersistent + 接口(interface),Delphi

delphi - 为什么提前创建 TRttiContext 会使我的 RTTI 测试运行得更快?

delphi - 通过单击该行中的任何单元格来选择 TStringGrid 中的一行。

delphi - 是否可以获得类属性的索引?

Delphi - 使用 10.2.1 重新编译应用程序会导致内存泄漏吗?

delphi - 固定枚举未返回 RTTI 属性 : is it a bug?