Lars Fosdal 1792 Posted November 26, 2018 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
Attila Kovacs 629 Posted November 26, 2018 (edited) 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 November 26, 2018 by Attila Kovacs 2 Share this post Link to post
Lars Fosdal 1792 Posted November 26, 2018 Thanks, @Attila Kovacs - I wonder how I could overlook GetDeclaredProperties? I guess I will have to blame lack of coffee. Share this post Link to post
Lars Fosdal 1792 Posted November 26, 2018 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
Guest Posted November 26, 2018 @Lars Fosdal, you should dole out some "reputation" to Mr. Kovacs! Simply click "Like", but you knew that. Share this post Link to post
Attila Kovacs 629 Posted November 26, 2018 (edited) @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 November 26, 2018 by Attila Kovacs Share this post Link to post