Jump to content
Lars Fosdal

property Items: TArray<TMyType> - enumerate props of TMyType?

Recommended Posts

I want to recursively walk the properties of MyVar: TMyOuterType - but the Items list may be empty.

How can I walk the base element type of Items, i.e. TMyType - when I have no instance data?

type
  TMyType = class
  public
    property One: string;
    property Two: string;
  end;
  
  TMyType2 = class(TMyType)
  public
    property Two: string;
  end;

  TMyType3 = class(TMyType2)
  public 
    property Three: string;
  end;
  
  TMyTypeArray = TArray<TMyType>; // i.e. polymorphic
  
  TMyOuterType = class
  public
    property Items: TMyTypeArray;
  end;
  
  var
    MyVar: TMyOuterType;

 

Share this post


Link to post

var

  ctx: TRttiContext;
  rt: TRttiType;
  tf: TRttiField;
  tft: TRttiDynamicArrayType;
  tc: TClass;
  prop: TRttiProperty;
 

code

 

 MyVar := TMyOuterType.Create;
  ctx := TRttiContext.Create;
  for tf in ctx.GetType(MyVar.ClassInfo).GetDeclaredFields do         // took FItems as a class Field as it was easier to work with
    if tf.Name = 'FItems' then                                                            // change it to GetDeclaredProperties for Properties  
    begin
      tft := tf.FieldType as TRttiDynamicArrayType;
      rt := tft.ElementType;
      for prop in rt.GetDeclaredProperties do
        writeln(prop.Name);
      Break;
    end;
 

Edited by Attila Kovacs
  • Like 2

Share this post


Link to post

Or ... lack of sleep.  I was looking at the wrong context.  I should have mentioned that I need to walk a complex structure, and I would like to do it recursively, and not specifically for this particular element type.

I need to use rt.GetProperties to get the inherited props as well.

 

Share this post


Link to post

@Lars Fosdal 

 

TMyType has no inherited properties so if the list is empty this is the max you can get. (According to your example)

If you have for example an object of TMyType3 type in the list, this is something else, then there is GetProperties and GetDeclaredProperties, or

 

if Item is TBaseClass then

begin

  tc := Item.ClassType;
  while tc <> TBaseClass do
  begin

   // GetDeclaredProperties comes here

   tc := tc.ClassParent;

  end;
end;

 

in this case you get the declared properties up to the TBaseClass which is not necessarily TObject so you are filtering with this your "own" properties.

I think you can implement the version which fits your needs and which is perhaps also a bit different as the example above. 

 

Edited by Attila Kovacs

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×