- I want to get the whole list of classes defined in a specific unit
- How can I get the list of all instances of those classes, irrespective of where they are created?
Asked
Active
Viewed 3,518 times
4

LU RD
- 34,438
- 5
- 88
- 296

Vibeeshan Mahadeva
- 7,147
- 8
- 52
- 102
-
sorry for late response , i am using xe2 – Vibeeshan Mahadeva Jan 26 '12 at 04:38
2 Answers
5
First before to answer your question, remember always include your delphi version in questions related to the Rtti.
1) Asumming which you are using a new version of delphi (>=2010) you can get the unit name of a type using the QualifiedName
property , from there you must check the IsInstance
property to determine if is a class.
Check the next sample.
{$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) The Rtti can't list the instances of the classes. because the Rtti is about type information and not of instances.

RRUZ
- 134,889
- 20
- 356
- 483
-
1
-
Yeah this will work too, unfortunally the `DeclaringUnitName` is part of specific rtti types, but in this case for instances is ok. In the answer I recommend parse the `QualifiedName` to get the unit name because in the past I found some cases where the unit name is not present in some types check ths question for more info [Getting the Unit Name wich belongs to any type (TRttiType)](http://stackoverflow.com/questions/3843628/getting-the-unit-name-wich-belongs-to-any-type-trttitype) – RRUZ Jan 25 '12 at 14:40
-
Thanks a lot. Oh, one more Q while I have your ear. Are `IsInstance` and `AsInstance` the idiomatic ways to do this as opposed to `is` or `as` operators? – David Heffernan Jan 25 '12 at 14:45
-
@DavidHeffernan `AsInstance` try to cast the type to `TRttiInstanceType` so will fail to types which not are instances (classes). – RRUZ Jan 25 '12 at 14:47
-
I read that other question now. It looks like the issue it refers to is when trying to find the unit name for any variety of `TRttiType`. But for an instance, and you are writing `IsInstance`, surely it's simpler and cleaner to use `DeclaringUnitName`? – David Heffernan Jan 25 '12 at 15:12
-
@DavidHeffernan , yes is much more cleaner use `DeclaringUnitName` and in this case works. In my answer I give a more general solution based on my experience because in the past I have issues resolving the unit name of some types. – RRUZ Jan 25 '12 at 15:15
-
OK, all clear now. I think that point would be better off in the answer than the comments. If you did that I'd be happy to delete all the comments and tidy up. – David Heffernan Jan 25 '12 at 15:17
3
Question 1
The following code does what you ask, relying on the new RTTI introduced in Delphi 2010:
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.
Question 2
There is no global registry of object instances.

David Heffernan
- 601,492
- 42
- 1,072
- 1,490