Skip to content

Instantly share code, notes, and snippets.

@ortuagustin
Last active November 27, 2016 00:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ortuagustin/80ccb3a39ed2a1625625dbba923fb80f to your computer and use it in GitHub Desktop.
Save ortuagustin/80ccb3a39ed2a1625625dbba923fb80f to your computer and use it in GitHub Desktop.
ClassRtti
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Rtti;
type
TFoo<T: class> = class
public
constructor Create;
end;
TSomeClass = class
public
procedure FooMethod;
end;
constructor TFoo<T>.Create;
var
ctx: TRttiContext;
Each: TRttiMethod;
begin
inherited Create;
for Each in ctx.GetType(T).GetMethods do
begin
Writeln(Each.ToString);
end;
end;
procedure TSomeClass.FooMethod;
begin
Writeln('TSomeClass.FooMethod');
end;
var
ClassFoo: TFoo<TSomeClass>;
begin
try
ClassFoo := TFoo<TSomeClass>.Create;
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
@jkour
Copy link

jkour commented Nov 27, 2016

If you replace TClass, with T in TFoo, then the compiler gives an error here:

for Each in ctx.GetType(AClass).GetMethods do

@ortuagustin
Copy link
Author

Updated the gist

@ortuagustin
Copy link
Author

mmm, maybe you meant this?

  TFoo<T: class> = class
  private
    FClass: TClass;
  public
    constructor Create(AClass: TClass);
  end;

  TSomeClass = class
  public
    procedure FooMethod;
  end;

  TDerivedClass = class(TSomeClass)
  public
    procedure BarMethod;
  end;

constructor TFoo<T>.Create(AClass: TClass);
var
  ctx: TRttiContext;
  Each: TRttiMethod;
begin
  inherited Create;
  FClass := AClass;
  for Each in ctx.GetType(FClass).GetMethods do
  begin
    Writeln(Each.ToString);
  end;
end;

ClassFoo := TFoo<TSomeClass>.Create(TDerivedClass);

@jkour
Copy link

jkour commented Nov 27, 2016

That is what I am trying to achieve:

program Project1;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Rtti;

type
  TFoo<T:class> = class
  private
    FClass: T;
  public
    constructor Create(AClass: T);
    procedure show;
  end;

  TSomeClass = class
  public
    procedure FooMethod;
  end;

constructor TFoo<T>.Create(AClass: T);
begin
  inherited Create;
  FClass := AClass;
end;

procedure TSomeClass.FooMethod;
begin
  Writeln('TSomeClass.FooMethod');
end;

procedure TFoo<T>.show;
var
  ctx: TRttiContext;
  Each: TRttiMethod;
  rtype: TRttiType;
begin
  rtype:=ctx.GetType((FClass as TObject).classInfo);
  for Each in rtype.GetMethods do
  begin
    Writeln(Each.ToString);
  end;
end;


var
  ClassFoo: TFoo<TSomeClass>;
  tmpClass: TSomeClass;

begin
  try
   tmpClass:=TSomeClass.Create;
    ClassFoo := TFoo<TSomeClass>.Create(tmpClass);
    ClassFoo.show;
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

@jkour
Copy link

jkour commented Nov 27, 2016

Thanks to your gist, I have my solution now :-)

Thanks a lot Agustin

@ortuagustin
Copy link
Author

I still don't get what is not working 😕
What's wrong with your last code? It compiled fine

What confuses me it's why are you using the generic if you are going to query an object. If you have the generic (which can be considered a parameter) why do you need the class in the constructor?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment