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;
2 Likes

Hi,

Is there any news about the usage of public properties?

The pas2js team was not yet able to handle this.

Thanks for the response. Hope this can be solved in future.