Reputation: 689
I coded a RttiHelper class, that among other things, can retrieve all field's names of a class. The procedure succesfully determines if a field is an object or an array, but it cannot determine if a field is a Record. Follows code:
unit Form1
interface
uses RttiHelper;
type
tMyRec = Record
...
end;
...
implementation
var MyRec : tMyRec;
procedure FormCreate (Sender: tObject);
begin
SetRec (@MyRec);
end;
unit RttiHelper
interface
type
tObjRec = class
Rec : Pointer;
end;
...
tRttiHelperClass = class (tObject)
private
fObjRec: tObjRec;
...
procedure GetFieldsNames;
...
public
...
procedure SetRec (aRec: Pointer);
...
published
...
constructor Create (aOwner: tComponent);
...
end;
implementation
constructor tRttiHelperClass.Create (aOwner: tComponent);
begin
fCtxt := tRttiContext.Create;
end;
procedure tRttiHelperClass.SetRec (aRec: Pointer);
begin
private
fObjectRec.Rec := aRec;
procedure GetFieldsNames;
end;
procedure tRttiHelperClass.GetFieldsNames;
var f : Word ;
fields : tRttiType;
begin
with fRttiContext do begin
RttiType := GetType (fObjRec.ClassType);
Fields := RttiType.GetFields;
for f := Low (fields) to High (fields) fo begin
if fields[f].GetValue (tObject (fObjRec^)).IsArray then // this works
...
if fields[f].GetValue (tObject (fObjRec^)).IsObject then // this works
...
if fields[f].GetValue (tObject (fObjRec^)).IsRecord then // "undeclared identifier IsRecord"
...
end;
end;
end.
I know that in order to work with Records, I must use tRttiRecordType, but I couldn't find the right way to do this. How is the correct code for determining if some field is a Record? Thanks.
Upvotes: 2
Views: 1451
Reputation: 34899
Try this instead:
if fields[f].FieldType.IsRecord then
From System.Rtti.TRttiField.FieldType and System.Rtti.TRttiType.IsRecord.
Now the underlying problem here is you cannot resolve the record fields from an untyped pointer. In order to do something like that, pass your record as a TValue.
procedure SetRec( aRec: TValue);
Call it this way:
SetRec(TValue.From(MyRec));
For a more complete tutorial how to do this and resolve the contents of a record, see Convert Record to Serialized Form Data for sending via HTTP.
Passing TValue works with classes and other types as well.
Upvotes: 2