Delphi 使用RTTI获取单元中定义的类和对象的完整列表 我想得到一个特定单元中定义的类的完整列表 如何获得这些类的所有实例的列表,而不管它们是在哪里创建的

Delphi 使用RTTI获取单元中定义的类和对象的完整列表 我想得到一个特定单元中定义的类的完整列表 如何获得这些类的所有实例的列表,而不管它们是在哪里创建的,delphi,delphi-xe2,rtti,Delphi,Delphi Xe2,Rtti,问题1 根据Delphi 2010中引入的新RTTI,以下代码满足您的要求: program FindClassesDeclaredInUnit; {$APPTYPE CONSOLE} uses SysUtils, Rtti, MyTestUnit in 'MyTestUnit.pas'; procedure ListClassesDeclaredInNamedUnit(const UnitName: string); var Context: TRttiContext; t:

问题1

根据Delphi 2010中引入的新RTTI,以下代码满足您的要求:

program FindClassesDeclaredInUnit;

{$APPTYPE CONSOLE}

uses
  SysUtils, Rtti, MyTestUnit in 'MyTestUnit.pas';

procedure ListClassesDeclaredInNamedUnit(const UnitName: string);
var
  Context: TRttiContext;
  t: TRttiType;
  DeclaringUnitName: string;
begin
  Context := TRttiContext.Create;
  for t in Context.GetTypes do
    if t.IsInstance then
    begin
      DeclaringUnitName := t.AsInstance.DeclaringUnitName;
      if SameText(DeclaringUnitName, UnitName) then
        Writeln(t.ToString, ' ', DeclaringUnitName);
    end;
end;

begin
  ListClassesDeclaredInNamedUnit('MyTestUnit');
  Readln;
end.


unit MyTestUnit;

interface

type
  TClass1 = class
  end;

  TClass2 = class
  end;

implementation

procedure StopLinkerStrippingTheseClasses;
begin
  TClass1.Create.Free;
  TClass2.Create.Free;
end;

initialization
  StopLinkerStrippingTheseClasses;

end.
问题2


对象实例没有全局注册表。

在回答您的问题之前,请记住在与Rtti相关的问题中始终包含您的delphi版本

1) 如果您使用的是新版本的delphi(>=2010),您可以使用属性获取类型的单元名称,从那里您必须检查
IsInstance
属性以确定是否为类

检查下一个样本

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Rtti,
  System.SysUtils;

procedure Test;
Var
 t : TRttiType;
  //extract the unit name from the  QualifiedName property
  function GetUnitName(lType: TRttiType): string;
  begin
    Result := StringReplace(lType.QualifiedName, '.' + lType.Name, '',[rfReplaceAll])
  end;

begin
 //list all the types of the System.SysUtils unit
  for t in TRttiContext.Create.GetTypes do
   if SameText('System.SysUtils',GetUnitName(t)) and (t.IsInstance) then
     Writeln(t.Name);
end;

begin
  try
    Test;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

2) Rtti不能列出类的实例。因为Rtti是关于类型信息而不是实例的。

DeclaringUnitName呢?使用它可以吗?是的,这也可以,不幸的是,
DeclaringUnitName
是特定rtti类型的一部分,但在这种情况下,对于实例是可以的。在回答中,我建议解析
QualifiedName
以获取单元名称,因为在过去,我发现某些类型中不存在单元名称,请检查该问题以了解更多信息,谢谢。哦,等我听你的时候再问一个问题。与
is
as
操作符相比,执行此操作的惯用方法是
IsInstance
asiinstance
吗?@DavidHeffernan
asiinstance
尝试将类型强制转换为
trttInstanceType
,因此将无法转换为非实例(类)的类型。我现在阅读了另一个问题。它所指的问题似乎是在试图为任何种类的
TRttiType
查找单元名称时出现的。但举个例子,如果您正在编写
IsInstance
,那么使用
DeclaringUnitName
肯定会更简单更干净吗?很抱歉,我使用的是xe2