Delphi RTTI能否在设计时查询项目代码中的类型?

Delphi RTTI能否在设计时查询项目代码中的类型?,delphi,rtti,design-time,Delphi,Rtti,Design Time,我想在设计时而不是运行时使用RTTI检查项目源文件中包含的类型 据我所知,这是不受支持的,但在的评论中的讨论表明,这是可能的,并且已经针对几个Delphi版本。这是我第一次听说这个功能是可用的,但到目前为止,我还无法为自己复制它 这是我的测试示例。它使用一个简单的TListBox子体TMyListBox,该子体有一个字符串属性TypeToExplore,当设置该字符串时,该字符串将用输入的限定类型名的属性填充列表框 unit MyListBox; interface uses SysUt

我想在设计时而不是运行时使用RTTI检查项目源文件中包含的类型

据我所知,这是不受支持的,但在的评论中的讨论表明,这是可能的,并且已经针对几个Delphi版本。这是我第一次听说这个功能是可用的,但到目前为止,我还无法为自己复制它

这是我的测试示例。它使用一个简单的
TListBox
子体
TMyListBox
,该子体有一个
字符串
属性
TypeToExplore
,当设置该字符串时,该字符串将用输入的限定类型名的属性填充列表框

unit MyListBox;

interface

uses
  SysUtils, Classes, Controls, StdCtrls;

type
  TMyListBox = class(TListBox)
  private
    FTypeToExplore : string;
    procedure SetTypeToExplore(const inValue: string);
    procedure FillWithTypeDetails;
  published
    property TypeToExplore : string read FTypeToExplore write SetTypeToExplore;
  end;

procedure Register;

implementation

uses
  RTTI, TypInfo;

procedure TMyListBox.SetTypeToExplore(const inValue: string);
begin
  if inValue = FTypeToExplore then
    Exit;

  FTypeToExplore := inValue;
  Clear;
  FillWithTypeDetails;
end;

procedure TMyListBox.FillWithTypeDetails;
var
  context : TRTTIContext;
  theType : TRttiType;
  properties : TArray<TRttiProperty>;
  prop : TRttiProperty;
begin
  theType := context.FindType(FTypeToExplore);
  if Assigned(theType) then begin
    properties := theType.GetProperties;
    for prop in properties do
      Items.Add(prop.Name);
  end else
    Items.Add('No type found');
end;

procedure Register;
begin
  RegisterComponents('Samples', [TMyListBox]);
end;

end.
unitmylistbox;
接口
使用
系统、类、控件、stdctrl;
类型
TMyListBox=类(TListBox)
私有的
FTypeToExplore:字符串;
过程SetTypeToExplore(常量无效:字符串);
用类型详细信息填写程序;
出版
属性TypeToExplore:string read FTypeToExplore write SetTypeToExplore;
结束;
程序登记册;
实施
使用
RTTI,TypInfo;
过程TMyListBox.SetTypeToExplore(const inValue:string);
开始
如果inValue=FTypeToExplore,则
出口
FTypeToExplore:=无效;
清楚的
填写字体细节;
结束;
程序TMyListBox.FillWithTypeDetails;
变量
语境:语境;
类型:trtti型;
性状:焦油;
财产:信托财产;
开始
类型:=context.FindType(FTypeToExplore);
如果已分配(类型),则开始
属性:=type.GetProperties;
对于属性中的道具,请执行以下操作:
添加项目(项目名称);
结束其他
Items.Add('未找到类型');
结束;
程序登记册;
开始
注册表组件('Samples',[TMyListBox]);
结束;
结束。
使用此
TMyListBox
组件I

  • 编译并安装到delphixeide中
  • 将组件DCU位置添加到IDE库路径
  • 重新启动IDE以确保
  • 创建一个新的空
    Project1
  • 将MyListBox1放到M1上
  • 保存、编译并运行
    Project1
  • 关闭
    Project1
    应用程序(但不关闭项目)
  • 在对象检查器中,将
    MyListBox1.TypeToExplore
    设置为
    Unit1.t或m1
MyListBox1
报告“未找到类型”,这与我对RTTI工作原理的理解一致,即在设计时,它只能探索安装到IDE中的包中包含的类型,而不能探索项目源文件

如果IDE确实能够检查项目中声明的类型,那么我缺少什么呢

问:您能否在设计时查询/利用DelphiIDE中的类型

A:当然可以:)

问:IDE是否直接使用RTTI

另外,IDE对类型、方法等的“知识”与运行时RTTI是不同的。好吧,这同样适用于Java内省/EclipseIDE/debugger或.Net反射/MSVSIDE/debugger

本文可能有助于:


通过阅读RTTI.pas源代码,我得出结论,Delphi RTTI无法检查IDE的当前项目。在设计时,RTTI能够检查IDE托管的包中的类型。它不能再检查了。

+1问得好。我很想知道答案是什么!!是否希望使用designtime和runtime中可用的限定类型名称的所有属性填充TListBox功能?@menjaraz:Yes designtime和runtime。此示例在运行时使用限定的类型名Unit1.TForm1可以很好地工作,但在设计时却不行。这里不是很安静….@LaKraven您实际上不需要调用其中任何一个those@paulsm4您链接到增强RTTI(D2010)之前的文章。这似乎与增强RTTI相关的问题无关。如果你说“如果它是旧的,它一定是错的”——那是胡说八道。如果您是说“当引入增强RTTI时,规则可能已经改变了”,那就更合理了。但我不这么认为。我在上面说过——我仍然相信——即使是最新/最好的XE2,“RTTI”是一种运行时的东西,或多或少独立于IDE(和调试器)。这里有更多的证据支持这一观点:附言:这篇文章仍然是一篇非常非常好的文章。IMHO…LaKraven断言增强型RTTI能够在设计时反思活动项目。所以我认为这个问题是关于增强型RTTI的。现在再看看我的包装单元生成器的原始源代码(最初是在2009年底为D2010编写的),我可以证实David在这里说的话!我的包装器单元生成器实际上正在创建一个与所选项目具有相同属性的包,并将其注册到IDE。。。然后是使用RTTI!现在我感到既困惑又有点愚蠢@莱克拉文我很高兴我们解决了这一切。我恢复了你对我另一个问题答案的编辑。你对另一个答案的接受可能有点让人困惑。我很惊讶,自从两年前写这篇文章以来,我已经忘记了多少我的方法!哦,太遗憾了。我期待着利用这个秘密RTTI能力。多亏了你们,这是一次有趣的讨论和实验。