Delphi 是否可以使用通用RTTI方法获得线性枚举的高低值?

Delphi 是否可以使用通用RTTI方法获得线性枚举的高低值?,delphi,Delphi,我的目标是为对象创建和生成随机值。 为此,我将遍历所有字段,并根据字段类型设置随机值。 例如,如果我找到一个整型字段,我给出一个随机整数值,如果我找到一个字符串,我有一个生成随机字符串值的方法,等等。 但是我对枚举有一个问题。 我知道对于非线性枚举,例如: TTypeNonLiear = (tnlNone = 1, tnlOther = 5, tnlAnother = 10); RTTI没有关于fieldtype的信息。 所以我将跳过它,没问题,但我想解决线性枚举类型的问题: TTypeLie

我的目标是为对象创建和生成随机值。 为此,我将遍历所有字段,并根据字段类型设置随机值。 例如,如果我找到一个整型字段,我给出一个随机整数值,如果我找到一个字符串,我有一个生成随机字符串值的方法,等等。 但是我对枚举有一个问题。 我知道对于非线性枚举,例如:

TTypeNonLiear = (tnlNone = 1, tnlOther = 5, tnlAnother = 10);
RTTI没有关于fieldtype的信息。 所以我将跳过它,没问题,但我想解决线性枚举类型的问题:

TTypeLiear=(tlUnknown=0,tlOther=1,tlOther=2)

如果我使用类似于线性枚举的代码:
Ord(Low(TTypeLiear))
Ord(High(TTypeLiear))
我可以获得随机范围,但是如何调用从RTTI获得信息的字段的Low和High

这将是一个示例代码:

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;
类型
{+M}
t类型非线性=(tnlNone=1,tnlOther=5,tnlAnother=10);
TTypeLiear=(tlUnknown=0,tlOther=1,tlOther=2);
TObjectX=类(TObject)
f非线性:t类型非线性;
FLinearEnum:t类型;
结束;
程序TForm45.btn2Click(发送方:TObject);
变量
CurContext:TRttiContext;
试验:TObjectX;
CurClassType:trtttype;
柯菲:柏油;
I:整数;
字段:TRttiField;
TypeValue:整数;
LFieldPointer:指针;
typedsmalint:SmallInt;
开始
测试:=TObjectX.Create;
CurContext:=TRttiContext.Create;
CurClassType:=CurContext.GetType(Test.ClassType);
CurFields:=CurClassType.GetFields;
//您可以在这里设置要在类型字段中设置的任何整数值。例如查询结果(AsInteger、AsOrdinal)
类型值:=1;
对于I:=0到长度(CurFields)-1 do
开始
字段:=CurFields[I];
如果分配了(Field.FieldType)和(Field.FieldType.TypeKind=tkEnumeration),则
开始
//这是解决方案,我直接在字段位置更改值
LFieldPointer:=指针(字节(测试)+字段偏移量);
typedsmalint:={这里我想生成随机值};
移动(typedsmalint,LFieldPointer^,Field.FieldType.TypeSize);
结束;
结束;
结束;
该类可用于检索有关枚举类型的特定信息,如允许的最小值和最大值

试试这个样品

LMin:= TRttiEnumerationType(Field.FieldType).MinValue;
LMax:= TRttiEnumerationType(Field.FieldType).MaxValue;
该类可用于检索有关枚举类型的特定信息,如允许的最小值和最大值

试试这个样品

LMin:= TRttiEnumerationType(Field.FieldType).MinValue;
LMax:= TRttiEnumerationType(Field.FieldType).MaxValue;

我将省略显式值:
TTypeLiear=(tlUnknown,tlOther,tlOther)
是否尝试使用
trttineumerationtype
LMin:=TRttiEnumerationType(Field.FieldType).MinValue
LMax:=trttineumerationtype(Field.FieldType).MaxValue完美RRUZ,这正是我想要的,我不知道它的存在。你能创造一个答案吗?文档是错误的。它说“具有特定值的枚举常量没有RTTI”。它应该说的是“具有非连续序数值、最小序数值不等于零或非单调序数值的枚举类型没有RTTI。@DavidHeffernan,:不连续枚举和不从零开始的枚举没有typeinfo。我将省略显式值:
TTypeLiear=(tlUnknown,tlOther,tlOther);
是否尝试使用
trttineumerationtype
类?
LMin:=trttineumerationtype(Field.FieldType).MinValue;
LMax:=trttineumerationtype(Field.FieldType).MaxValue;
Perfect RRUZ,这正是我要找的,我不知道它的存在。你能创建一个答案吗?文档是错误的。它说“具有特定值的枚举常量没有RTTI”。它应该说的是”具有非连续序数值、最小序数值不等于零或非单调序数值的枚举类型没有RTTI。@DavidHeffernan,:不连续枚举和不从零开始的枚举没有typeinfo。我知道这与此无关,但我没有找到任何方法与您联系。我正在使用
vclstylesinno.dll
1.5.4.1版本,但它没有加载滚动条的样式,例如在“浏览”对话框中,滚动条将没有该样式。同时,该样式也不会影响窗口框架。是否有任何新版本或修复程序?我知道这与此无关,但我没有找到任何方法与您联系。我使用的是
vclstylesinno.dll
1.5.4.1版本,但它没有加载滚动条的样式,例如在浏览对话框中,滚动条将不具有该样式。同时,该样式也不会影响窗口框架。是否有任何新版本或修复程序?