Delphi Rtti: Explore properties of interfaces?
Asked Answered
M

4

10

Is there a way to explore a interface's properties with Rtti?

The following code does not work:

procedure ExploreProps;
var
  Ctx: TRttiContext;
  RttiType: TRttiType;
  RttiProp: TRttiProp;
begin
  RttiType := Ctx.GetType(TypeInfo(IMyInterface));
  for RttiProp in RttiType.GetProperties do
    Writeln(RttiProp.ToString);
end;

Has anyone a solution how to do this correctly?

Montana answered 12/9, 2010 at 13:46 Comment(0)
E
6

Interfaces are collections of functions. They don't really have properties the way objects do; that's just a bit of syntactic sugar that the compiler adds for you to make it easier to write code for them. The difference is that on objects, properties allow controlled access to private and protected members, whereas on interfaces, all members are public so there's no need for the properties.

Estrone answered 12/9, 2010 at 14:44 Comment(3)
Ok, but exploring a interfaces methods doesn't work either... Just replaced the for loop by using RttiType.GetMethods, still no results.Montana
@Christian: I just looked at the code for the RTTI system, and a lot of interfaces in the standard libraries are set up with no RTTI generated for them. I'm not sure what the rules are for generating extended RTTI for interface types, since it seems to be different from generating extended RTTI for classes or records. Maybe Barry Kelly or Allen Bauer could answer this one?Estrone
An interface type needs to have {M+} applied to it in order for TRttiType.GetMethods() to report the interface's methods.Honduras
C
1

As I known, there is no support for normal interfaces. You could add {$M+} and then try again.

Compression answered 13/9, 2010 at 0:42 Comment(0)
J
1

Add this function in your interface

function GetObject: TObject;

and implement it in the class. the use the GetObject function with RTTI routines

var
  obj: IPerson;
begin
  obj := TPerson.Create;
  Count := GetPropList(obj.GetObject.ClassInfo, tkAny, @List);
end;

Please note that your class should be inherited from TInterfacedPersistent not TInterfacedObject

TPerson = class(TInterfacedPersistent, IPerson)
Jonasjonathan answered 5/12, 2012 at 21:22 Comment(0)
O
-1

late answer, but you could typecast your interfae to TObject, e.g.

RttiType := Ctx.GetType(TObject(IMyInterface).ClassInfo);
Oppression answered 20/1, 2011 at 14:17 Comment(1)
That is incorrect and dangerous. Due to memory layout interfaces can not be cast back to objects. You would have to add a function to the interface to get back to the object (like in @FLICKERs answer).Monarchy

© 2022 - 2024 — McMap. All rights reserved.