我的目标是为对象创建和生成随机值。 为此,我将浏览所有字段并根据字段类型设置随机值。 例如,如果我找到一个整数字段,我给出一个随机整数值,如果我找到一个字符串,我有一个生成随机字符串值的方法,依此类推。 但是我的枚举问题。 我知道对于非线性枚举,例如:
TTypeNonLiear = (tnlNone = 1, tnlOther = 5, tnlAnother = 10);
RTTI没有关于fieldtype的信息。 所以我会跳过它,没问题,但我想解决线性枚举类型的问题:
TTypeLiear = (tlUnknown = 0, tlOther = 1, tlAnother = 2);
如果我使用类似线性枚举的代码:
Ord(Low(TTypeLiear))
或Ord(High(TTypeLiear))
我可以获得使其随机化的范围,但如何为从RTTI获取信息的字段调用低和高。
这是一个示例代码:
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;
答案 0 :(得分:6)
TRttiEnumerationType
类可用于检索有关枚举类型的特定信息,例如允许的最小值和最大值。
试试这个样本
LMin:= TRttiEnumerationType(Field.FieldType).MinValue;
LMax:= TRttiEnumerationType(Field.FieldType).MaxValue;