0

Why this won't compile ?

(Code from a custom JSON Interceptor)

procedure myproc(MyObject: TObject);

  procedure test(C: TClass);
  begin
    var ctx := TRttiContext.Create;
    var typ := ctx.GetType(C);
    for var fld in typ.GetFields do
    begin
      if fld.Name = 'anyfield' then
      begin
         TObjectList<Fld.ClassType>.Create(True);
      end;
    end;
    typ.Free;
    ctx.Free;
  end;

begin
  Test( MyOrgObject );
end;

something is wrong with : TObjectList<Fld.ClassType>.Create(True);

Any Ideas ? Thank you

OK, What I have is :

procedure TqBitObjectListInterceptor.StringReverter(Data: TObject; Field, Arg: string);
begin   
  if (Data is TqBitLogsType) and (Field = 'Flogs') then
  begin
    TqBitLogsType(Data).Flogs := TObjectList<TqBitLogType>.Create(True);
  end else
  if (Data is TqBitPrefsType) and (Field = 'Flist') then
  begin
    TqBitPrefsType(Data).Flogs := TObjectList<TqBitPrefsType>.Create(True);
  end else... 
end;
   

and so on for each pair Type/Field with the same code I would like to be able to assign the Data.Field to a TObjectList using RTTI :


procedure TqBitObjectListInterceptor.StringReverter(Data: TObject; Field, Arg: string);

  function Convert(C: TClass; F: string): boolean;
  if (Data is C) and (Field = F) then
  begin
    var ctx := TRttiContext.Create;
    var typ := ctx.GetType(Data);
    for var fld in typ.GetFields do
    begin
      if fld.Name = F then
      begin
        fld.SetValue( TObjectList<C>.Create(True) );
      end;
       TObjectList<C>.Create(True); <<<<<
      end;
    end;
    typ.Free;
    ctx.Free;
    Result := True;
  end;
  
begin
  Convert(TqBitLogsType, 'Flogs');
  Convert(TqBitPreferenceType, 'Flist');
end;

For Reference : https://sourceforge.net/p/qbitvcl/code/HEAD/tree/trunk/

Unit : uqBitAPITypes.pas procedure TqBitObjectListInterceptor.StringReverter(Data: TObject; Field, Arg: string);

  • This doesn't compile because generics are crystallised at compile time, but you are trying to postpone this until runtime. – David Heffernan Oct 31 '21 at 13:21
  • Understood. Is there a way to achieve this ? Interfaces ? – Laurent Meyer Oct 31 '21 at 15:07
  • There is not enough code context about your end goal, so you may have additional issues later on or you are using completely wrong tool for the job. Having said that you can solve construction by using `TObjectList.Create(True)` since code generated for generic object list holding `TObject` and any other descendant class will be the same. – Dalija Prasnikar Oct 31 '21 at 15:50
  • @Laurent To achieve what? I mean what you asked for in the question is impossible, so no, there's no way to achieve it. However, your problem does have a solution. You should ask abiut your problem. – David Heffernan Oct 31 '21 at 16:52
  • David, I am just wondering. I have already a "stupid" solution : copy/paste. Thank you for your time. – Laurent Meyer Oct 31 '21 at 16:54
  • Also note that `ctx.GetType(Data)` won't work, either, as `GetType()` expects a `PTypeInfo` or a `TClass`, not a `TObject`. – Remy Lebeau Oct 31 '21 at 18:44
  • Yes Remy it should be C – Laurent Meyer Oct 31 '21 at 18:56

0 Answers0