My goal is to create and generate random values for an object(s). For that I'm going through all it's fields and setting random values based on the field type. For instance if I find an integer field I give a random integer value, if I find a string I have a method that generates random string values and so on. But I have a problem with enums. I know that for non linear enums like:
TTypeNonLiear = (tnlNone = 1, tnlOther = 5, tnlAnother = 10);
RTTI does not have information about the fieldtype. So I will just skip it, no problem, but I'd like to solve the problem for linear enums types:
TTypeLiear = (tlUnknown = 0, tlOther = 1, tlAnother = 2);
If I use something like code for linear enums:
Ord(Low(TTypeLiear))
or Ord(High(TTypeLiear))
I can get the ranges that I need to make it random but how to call Low and High for a field that I got the information from RTTI.
This would be a sample code:
type
{+M}
TTypeNonLiear = (tnlNone = 1, tnlOther = 5, tnlAnother = 10);
TTypeLiear = (tlUnknown = 0, tlOther = 1, tlAnother = 2);
TObjectX = class(TObject)
FNonLinearEnum: TTypeNonLiear;
FLinearEnum: TTypeLiear;
end;
procedure TForm45.btn2Click(Sender: TObject);
var
CurContext: TRttiContext;
Test: TObjectX;
CurClassType: TRttiType;
CurFields: TArray<TRttiField>;
I: Integer;
Field: TRttiField;
TypeValue: Integer;
LFieldPointer: Pointer;
TypedSmallInt: SmallInt;
begin
Test := TObjectX.Create;
CurContext := TRttiContext.Create;
CurClassType := CurContext.GetType(Test.ClassType);
CurFields := CurClassType.GetFields;
//Here you can set any integer value you'd like to set in the type field. For example the result of query (AsInteger, AsOrdinal)
TypeValue := 1;
for I := 0 to Length(CurFields) -1 do
begin
Field := CurFields[I];
if Assigned(Field.FieldType) and (Field.FieldType.TypeKind = tkEnumeration) then
begin
//Here is the solution, I change the value direct in the field position
LFieldPointer := Pointer(PByte(Test) + Field.Offset);
TypedSmallInt := {HERE I WANNA GENERATE THE RANDOM VALUE};
Move(TypedSmallInt, LFieldPointer^, Field.FieldType.TypeSize);
end;
end;
end;