Forum > Beginners

Get class fields names and assign to record fields

(1/2) > >>

noszone:
I have a class:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---TData = class  public    id: largeint;    name: String;    constructor Create(aID: Integer; const aName: String);  end;
I want to run a loop (or other action) in order to get fields ID and NAME of the above class. Also I have record:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---DataRecord=record    id:largeint;    name:string;  end;  DataType=array of DataRecord;
In loop I want automatically assign class property to record property, like id=id, name=name.

e.g function:
for i:=0 to dataClass.fieldscount do
record[prop]=dataClass[prop]
result:=record;

So value in class.id should be written to record.id and value in class.name have to be written to record.name.

I know I can manualy assign class.id=record.id, but I want that program itself have to find names (in class and record they are identical).

Is it possible in some way? Thanks.

PascalDragon:

--- Quote from: noszone on January 29, 2023, 12:18:05 pm ---Is it possible in some way? Thanks.

--- End quote ---

For the class you need to enable generation of published RTTI by putting {$M+} in front of the class and then declaring your fields not as fields, but as published properties. You can then use the RTTI units TypInfo or Rtti to access the properties.
For records there currently is no way (except of you manually knowing the order of the fields, then you can also use the RTTI which does not contain names, only offsets), but there will be once extended RTTI is implemented.

jamie:
Wouldn't a TCollections work for that?

cdbc:
Hi
Something like this:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program rttitest; uses    TypInfo; type    TMyRec = record        p1: Integer;        p2: string;        p3: double;    end; var    td: PTypeData;    ti: PTypeInfo;    mf: PManagedField;    p: Pointer;    f: Pointer;     r: TMyRec; begin    r.p1 := 312;    r.p2 := 'foo-bar';    r.p3:= 3.1459;     ti := TypeInfo(r);    td := GetTypeData(ti);     Writeln('Managed field count: ',td^.TotalFieldCount); // Get count of record fields     // After ManagedFldCount TTypeData contains list of the TManagedField records    // So ...    // p := @(td^.RecInitData^.ManagedFieldCount); // Point to the ManagedFldCount ...    p := @(td^.TotalFieldCount); // Point to the ManagedFldCount ...    // Next line works for both    Inc(p, SizeOf(td^.TotalFieldCount)); // Skip it     mf := p; { And now in the mf we have data about first record's field }    Writeln('Typeref^.Name: ',mf^.TypeRef^.Name);     WriteLn('Value: ',r.p1); // Current value    f := @r;    Inc(f, mf^.FldOffset); // Point to the first field    Integer(f^) := 645; // Set field value    Writeln('New value: ',r.p1); // New value     // Repeat for the second field    Inc(p, SizeOf(TManagedField));    mf := p;    Writeln('Typeref^.Name: ',mf^.TypeRef^.Name);     WriteLn('Value: ',r.p2);    f := @r;    Inc(f, mf^.FldOffset);    string(f^) := 'abrakadabra';    Writeln('New value: ',r.p2);     // Repeat for the third field    Inc(p, SizeOf(TManagedField));    mf := p;    Writeln('Typeref^.Name: ',mf^.TypeRef^.Name);     WriteLn('Value: ',r.p3);    f:= @r;    Inc(f, mf^.FldOffset);    double(f^):= 7.62;    Writeln('New value: ',r.p3);    writeln('Press Enter');    Readln;end. ... or google "rtti record stackoverflow"
Hth
Regards Benny

noszone:
Thanks PascalDragon for your expertise, and others for ideas and provided code. I got a plan to use the subject in project, but after testing, seems I will use it "manually".

Could someone advise if array of objects is good idea to keep inside some huge rows data inside? I noted, for array of objects I have to each time manually create some parts of it. I guess is not the use case.

Navigation

[0] Message Index

[#] Next page

Go to full version