Delphi TrtitContext GetTypes找不到我的类型

Delphi TrtitContext GetTypes找不到我的类型,delphi,rtti,Delphi,Rtti,我试图列出我的接口和类来构建一个框架,但是GetTypes()方法找不到我的类型,我需要在我的源代码中做些什么才能使之成为可能 unit untPrincipal; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Rt

我试图列出我的接口和类来构建一个框架,但是GetTypes()方法找不到我的类型,我需要在我的源代码中做些什么才能使之成为可能

unit untPrincipal;

interface

uses
   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Rtti, Vcl.StdCtrls, System.TypInfo;

type
   TForm1 = class(TForm)
      btnTeste: TButton;
      mmoSaida: TMemo;
      procedure btnTesteClick(Sender: TObject);
   private
      { Private declarations }
   public
      { Public declarations }
   end;

   IMyInterface = interface(IInterface)
      ['{60B148AA-0750-432F-8AC0-1423707803AC}']
      procedure Fazer;
   end;

   IMyInterface2 = interface(IInvokable)
      ['{80A5566A-D8A4-44A7-AEC6-7874F95EFA13}']
      procedure Fazer;
   end;

{$M+}

   IMyInterface3 = interface
      ['{7A6ED55C-2A96-4BCF-ADD1-65159B37F258}']
      procedure Fazer;
   end;
{$M-}

   TMyClass = class(TInterfacedObject, IMyInterface)
   public
      procedure Fazer;
   end;

   TMyClass2 = class(TInterfacedObject, IMyInterface2)
   public
      procedure Fazer;
   end;

   TMyClass3 = class(TInterfacedObject, IMyInterface3)
   public
      procedure Fazer;
   end;

var
   Form1: TForm1;

implementation

{$R *.dfm}


procedure TForm1.btnTesteClick(Sender: TObject);
var
   ctx: TRttiContext;
   ctypes: TArray<TRttiType>;
   ctype: TRttiType;
begin
   mmoSaida.Clear;
   ctx := TRttiContext.Create;
   try
      ctypes := ctx.GetTypes();
      for ctype in ctypes do
      begin
         mmoSaida.Lines.Add(ctype.ToString)
      end;
   finally
      ctx.Free;
   end;
end;

{ TMyClass }

procedure TMyClass.Fazer;
begin
   ShowMessage('procedure TMyClass.Fazer;');
end;

{ TMyClass2 }

procedure TMyClass2.Fazer;
begin
   ShowMessage('procedure TMyClass2.Fazer;');
end;

{ TMyClass3 }

procedure TMyClass3.Fazer;
begin
   ShowMessage('procedure TMyClass3.Fazer;');
end;

end.
unit;
界面
使用
Winapi.Windows、Winapi.Messages、System.SysUtils、System.Variants、System.Classes、Vcl.Graphics、,
控件、窗体、对话框、系统Rtti、Vcl.StdCtrls、系统TypInfo;
类型
TForm1=类(TForm)
btnTeste:t按钮;
mmoSaida:TMemo;
程序btnTesteClick(发送方:ToObject);
私有的
{私有声明}
平民的
{公开声明}
终止
IMyInterface=接口(i接口)
[{60B148AA-0750-432F-8AC0-1423707803AC}]
法泽程序;
终止
IMyInterface2=接口(IInvokable)
[{80A5566A-D8A4-44A7-AEC6-7874F95EFA13}]
法泽程序;
终止
{$M+}
IMyInterface3=接口
[{7A6ED55C-2A96-4BCF-ADD1-65159B37F258}]
法泽程序;
终止
{$M-}
TMyClass=类(TInterfacedObject,IMyInterface)
平民的
法泽程序;
终止
TMyClass2=类(TInterfacedObject,IMyInterface2)
平民的
法泽程序;
终止
TMyClass3=类(TInterfacedObject,IMyInterface3)
平民的
法泽程序;
终止
变量
表1:TForm1;
实施
{$R*.dfm}
程序TForm1.btnTesteClick(发送方:ToObject);
变量
ctx:trtti上下文;
类型:柏油虫;
ctype:TrtType;
开始
很清楚;
ctx:=TRttiContext.Create;
尝试
ctypes:=ctx.GetTypes();
对于ctypes中的ctypes do
开始
mmoSaida.Lines.Add(ctype.ToString)
终止
最后
免费;
终止
终止
{TMyClass}
程序TMyClass.Fazer;
开始
ShowMessage('procedure TMyClass.Fazer;');
终止
{TMyClass2}
程序TMyClass2.Fazer;
开始
ShowMessage('procedure TMyClass2.Fazer;');
终止
{TMyClass3}
程序TMyClass3.Fazer;
开始
ShowMessage('procedure TMyClass3.Fazer;');
终止
终止
上面的代码列出了几种类型,包括TForm1和其他简单类型。但它既没有列出我的接口,也没有列出我的类

Delphi 10.3更新1(版本26.0.33219.4899)


谢谢

您需要以某种方式注册类型(如工厂概念)。 使用普通类工厂,可以将类添加到工厂类列表中。同样的方法也适用于RTTI,只有在“使用”该类时才会自动添加RTTI

但在这两种情况下,您都不希望使用类工厂的例程/单元链接到包含类的实际单元(松散处理)

因此,为了实现这一点,您可以将“TMyClass.Classname”添加到定义了“TMyClass”的单元的“initialization”部分。那么Rtti就会知道了。
这样,就不需要在应用程序的主单元中“使用”类。

因为您没有使用/创建任何类型,它们不会包含在运行时中,因此RTTI没有找到它们有一些技术可以使用。@PeterWolf我的问题是我将一个接口传递给一个构造函数,它用我的属性扫描类后面的系统,一旦找到,该函数将构建给定的对象,如果我在某处引用该类,该函数就已经工作了,但我不想这样做。@whosrdaddy这通过在某个点引用我的类来解决我的问题,例如:TMyClass.ClassName();在我的代码的任何部分中,但是我必须在我的代码的任何部分中引用该类是有意义的,因为它“不使用”该类,所以GetTypes()方法不会在RTTI中列出它。但是为了更好地使用框架,我们的想法是不必引用类。对于TMyClass.Classname(),我将使用这种方法。