RTTI: read and write values to properties/fields of an instance

Hi,

I have a class (fictitious example)

type TEmployee = class (TObject)
FirstName: string;
LastName: string;
DateOFBirth: TDateTime;
end;

I create an instance of this class (var emp: TEmployee).

How can I read and write the values of this instance ?

I was looking into the code stated elsewhere:

var
PropList : TTypeMemberPropertyDynArray;
begin
PropList := GetPropList(emp);
for p in PropList do
begin
console.log(p.TypeInfo.Name);
end;
end;

but PropList always seems to be empty ? It does not make a difference whether I use fields or properties in the class or properties, change the accessibility, ...

Or should I register TEmployee somehow for the RTTI to be able to inspect it ?

Thanks

  TTestClass = class
  private
    FSomeValue: Integer;
  published
    property SomeValue: Integer read FSomeValue write FSomeValue;
  end;

uses
  System.Rtti, System.TypInfo;

procedure ReadAndWriteProperty;
var
  Context: TRttiContext;
  RttiType: TRttiType;
  RttiProperty: TRttiProperty;
  TestObj: TTestClass;
  v: TValue;
begin

  TestObj := TTestClass.Create;
  try
    // Create RTTI Context
    Context := TRttiContext.Create;

    // Get RTTI Type of the class
    RttiType := Context.GetType(TTestClass);

    // Get the property info for 'SomeValue'
    RttiProperty := RttiType.GetProperty('SomeValue');

    if Assigned(RttiProperty) then
    begin
      // Write a value to SomeValue using RTTI
      v := TValue.From<Integer>(42);
      RttiProperty.SetValue(TestObj, v);

      // Read the value of SomeValue using RTTI
      Writeln('SomeValue: ', RttiProperty.GetValue(TestObj).AsInteger);
    end
    else
      Writeln('Property not found.');

  finally
    TestObj.Free;
    Context.Free;
  end;
end;
1 Like

Thanks Bruno. This works !

Now I am trying to use GetField so I can read/write the values of (public) variables (instead of published properties), but this does not seem to work ?

Not sure GetField is intended like this ?

I assume this is still a limitation as read in How to get fields using RTTI ?

Thanks

I'll need to check for public properties what the latest state is of the pas2js team.
At this moment, I see this indeed still applies to published properties.

Thanks Bruno,

For now I will do it it in Javascript, like this:

function GetFieldCount(obj: TObject): integer;
var value: integer;
begin
  asm
    value = Object.keys(obj).length;
  end;
  result := value;
end;

function GetFieldValue (obj: TObject; fieldName: string): string;
var value: string;
begin
  asm
    value = obj [fieldName];
  end;
  result := value;
end;

procedure SetFieldValue (obj: TObject; fieldName: string; value: string);
begin
  asm
    obj[fieldName] = value;
  end;
end;
1 Like