发现首次发布具有多个继承级别的属性的类

发布于 2024-08-08 14:15:44 字数 1072 浏览 6 评论 0原文

使用 Typinfo 单元,可以很容易地枚举属性,如以下代码片段所示:

procedure TYRPropertiesMap.InitFrom(AClass: TClass; InheritLevel: Integer = 0);
var
  propInfo: PPropInfo;
  propCount: Integer;
  propList: PPropList;
  propType: PPTypeInfo;
  pm: TYRPropertyMap;
  classInfo: TClassInfo;
  ix: Integer;

begin
  ClearMap;

  propCount := GetPropList(PTypeInfo(AClass.ClassInfo), propList);
  for ix := 0 to propCount - 1 do
  begin
    propInfo := propList^[ix];
    propType := propInfo^.PropType;

    if propType^.Kind = tkMethod then
      Continue; // Skip methods
    { Need to get GetPropInheritenceIndex to work
    if GetPropInheritenceIndex(propInfo) > InheritLevel then
      Continue; // Dont include properties deeper than InheritLevel
    }
    pm := TYRPropertyMap.Create(propInfo.Name);
    FList.Add(pm);
  end;
end;

但是,我需要的是找出每个属性继承的确切类。 例如,在 TControl 中,Tag 属性来自 TComponent,它的继承深度为 1(0 是 TControl 本身中声明的属性,例如 Cursor)。

如果我知道哪个类首先定义了该属性,那么计算继承深度就很容易。就我而言,财产首次获得公开知名度的地方就是它首次出现的地方。

我正在使用 Delphi 2007。如果需要更多详细信息,请告诉我。所有帮助将不胜感激。

Using the Typinfo unit, it is easy to enumerate properties as seen in the following snippet:

procedure TYRPropertiesMap.InitFrom(AClass: TClass; InheritLevel: Integer = 0);
var
  propInfo: PPropInfo;
  propCount: Integer;
  propList: PPropList;
  propType: PPTypeInfo;
  pm: TYRPropertyMap;
  classInfo: TClassInfo;
  ix: Integer;

begin
  ClearMap;

  propCount := GetPropList(PTypeInfo(AClass.ClassInfo), propList);
  for ix := 0 to propCount - 1 do
  begin
    propInfo := propList^[ix];
    propType := propInfo^.PropType;

    if propType^.Kind = tkMethod then
      Continue; // Skip methods
    { Need to get GetPropInheritenceIndex to work
    if GetPropInheritenceIndex(propInfo) > InheritLevel then
      Continue; // Dont include properties deeper than InheritLevel
    }
    pm := TYRPropertyMap.Create(propInfo.Name);
    FList.Add(pm);
  end;
end;

However, what I need is to figure out the exact class from which each property inherits.
For example in TControl, the Tag property comes from TComponent, which gives it an inheritance depth of 1 (0 being a property declared in TControl itself, such as Cursor).

Calculating the inheritance depth is easy if I know which class first defined the property. For my purposes, wherever a property first gained published visibility is where it first appeared.

I am using Delphi 2007. Please let me know if more detail is required. All help will be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

从﹋此江山别 2024-08-15 14:15:44

这对我有用。
关键是从传递的子 TypeInfo 中获取父 TypeInfo

procedure InheritanceLevel(AClassInfo: PTypeInfo; const AProperty: string; var level: Integer);
var
  propInfo: PPropInfo;
  propCount: Integer;
  propList: PPropList;
  ix: Integer;
begin
  if not Assigned(AClassInfo) then Exit;
  propCount := GetPropList(AClassInfo, propList);
  for ix := 0 to propCount - 1 do
  begin
    propInfo := propList^[ix];
    if propInfo^.Name = AProperty then
    begin
      Inc(level);
      InheritanceLevel(GetTypeData(AClassInfo).ParentInfo^, AProperty, level)
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  level: Integer;
begin
  level := 0;
  InheritanceLevel(PTypeInfo(TForm.ClassInfo), 'Tag', level);
end;

This works for me.
The crux is getting the parent's TypeInfo from the passed through child TypeInfo

procedure InheritanceLevel(AClassInfo: PTypeInfo; const AProperty: string; var level: Integer);
var
  propInfo: PPropInfo;
  propCount: Integer;
  propList: PPropList;
  ix: Integer;
begin
  if not Assigned(AClassInfo) then Exit;
  propCount := GetPropList(AClassInfo, propList);
  for ix := 0 to propCount - 1 do
  begin
    propInfo := propList^[ix];
    if propInfo^.Name = AProperty then
    begin
      Inc(level);
      InheritanceLevel(GetTypeData(AClassInfo).ParentInfo^, AProperty, level)
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  level: Integer;
begin
  level := 0;
  InheritanceLevel(PTypeInfo(TForm.ClassInfo), 'Tag', level);
end;
[旋木] 2024-08-15 14:15:44

我不知道您是否可以使用 Delphi 2007 中提供的 RTTI 找到它。TComponent 树中的大多数属性在原始类中声明为 protected,然后重新声明为 published再往下,您只有已发布成员的 RTTI。

当我看到他比我先一步时,我正要描述一些与 Lieven 的解决方案非常相似的东西。这将找到发布该属性的第一个类(如果这就是您要查找的内容),但它不会找到该属性最初声明的位置。如果您需要,您需要 Delphi 2010 的扩展 RTTI。

I don't know if you can find this using the RTTI available in Delphi 2007. Most properties in the TComponent tree are declared as protected in the original class, and then redeclared as published further down, and you only have RTTI for published members.

I was right about to describe something very similar to Lieven's solution when I saw that he'd beat me to it. This will find the first class where the property was published, if that's what you're looking for, but it won't find where the property was originally declared. You need Delphi 2010's extended RTTI if you wanted that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文