-3

I'm trying to find all Properties with a TStrings descendant type on an Object.

Here is what I've tried sofar:

Place a Memo and a Chart on a form and then this code.

procedure TForm1.FormCreate(Sender: TObject);
var
  aObject: TObject;
begin
  for aObject in GetItemsObjects(Chart1) do
    Memo1.Lines.Add(aObject.ClassName);
end;

class function TForm1.GetItemsObjects(aObject: TObject): TArray<TObject>;
var
  RttiProperty: TRttiProperty;
  RttiType: TRttiType;
  ResultList: TList<TObject>;
  PropertyValue: TValue;
  PropertyObject: TObject;
  s: String;
begin
  ResultList := TList<TObject>.Create;
  try
    RttiType := RttiContext.GetType(aObject.ClassType);
    for RttiProperty in RttiType.GetProperties do
    begin
      PropertyValue := RttiProperty.GetValue(aObject);

      if (not PropertyValue.IsObject) or (PropertyValue.IsEmpty) then
        continue;

      try
        PropertyObject := PropertyValue.AsObject;

        s := PropertyObject.ClassName;

        if (PropertyObject is TStrings) then
          ResultList.Add(PropertyObject)
        else
          ResultList.AddRange(GetItemsObjects(PropertyObject));
      except

      end;
    end;

  finally
    Result := ResultList.ToArray;
    ResultList.Free;
  end;
end;

The problem is that I get an stack overflow. Even though I've tried to stop the recursion with this code:

        if (PropertyObject is TStrings) then
          ResultList.Add(PropertyObject)
        else
          ResultList.AddRange(GetItemsObjects(PropertyObject));
Jens Borrisholt
  • 6,174
  • 1
  • 33
  • 67
  • Well, then don't do that recursive call `ResultList.AddRange(GetItemsObjects(PropertyObject));`. – Victoria Mar 27 '18 at 12:54
  • @Victoria you missed the point – Jens Borrisholt Mar 27 '18 at 14:18
  • @DavidHeffernan you missed the description of the problem "The problem are that it breaks down deep inside the VCL code. I've tried both the Memo and the Chart" Stack trace doesn't make sense since it's deep down the VCL – Jens Borrisholt Mar 27 '18 at 14:19
  • 2
    I didn't miss it. It just isn't enough. "it breaks down" tells us nothing. A stack trace and the exception message (verbatim) is what we should have. – David Heffernan Mar 27 '18 at 14:25
  • Do you want those properties that per property type are TStrings or descendant or all properties that have objects who are descendants of TStrings? – Stefan Glienke Mar 27 '18 at 14:25
  • @DavidHeffernan better error description. I restarted my Delphi and got some more meaningfull exception – Jens Borrisholt Mar 27 '18 at 14:33
  • Yes, then I certainly missed the point. Sorry, but I don't know how deep you wanted to check a certain control to have `TStrings` descendand properties. For me it sounds like you wanted to get list of properties that are `TStrings` descendants. Not level deeper. – Victoria Mar 28 '18 at 00:38

1 Answers1

3

Your code is causing a stack overflow because you are recursively calling GetItemsObjects which also scans properties like Parent from TControl.

If you really want to recursively do a deep scan of TStrings properties then you need to make sure to not revisit the same objects again - keep track of them with a list or something.

Stefan Glienke
  • 20,860
  • 2
  • 48
  • 102