【问题标题】:Is it possible to get the Low-High value of a linear enum with generic RTTI approach?是否可以使用通用 RTTI 方法获得线性枚举的低-高值?
【发布时间】:2018-03-12 15:29:58
【问题描述】:

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

TTypeNonLiear = (tnlNone = 1, tnlOther = 5, tnlAnother = 10);

RTTI 没有关于字段类型的信息。 所以我会跳过它,没问题,但我想解决线性枚举类型的问题:

TTypeLiear = (tlUnknown = 0, tlOther = 1, tlAnother = 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;

【问题讨论】:

  • 我会省略显式值:TTypeLiear = (tlUnknown, tlOther, tlAnother);
  • 您是否尝试过使用TRttiEnumerationType 类? LMin := TRttiEnumerationType(Field.FieldType).MinValue;LMax := TRttiEnumerationType(Field.FieldType).MaxValue;
  • 完美的RRUZ,这正是我要找的,我不知道它的存在。你能创造一个答案吗?
  • 文档有误。它说“具有特定值的枚举常量没有 RTTI”。它应该说的是“具有非连续序值、最小序值不等于零或非单调序值的枚举类型没有RTTI。
  • @DavidHeffernan, from the horses mouth不连续的枚举和不从零开始的枚举没有类型信息。

标签: delphi


【解决方案1】:

TRttiEnumerationType 类可用于检索有关枚举类型的特定信息,例如允许的最小值和最大值。

试试这个示例

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

【讨论】:

  • 我知道这里不相关,但是我没有找到任何联系方式。我正在使用vclstylesinno.dll 1.5.4.1 版本,但它没有加载滚动条的样式,例如在浏览对话框中,滚动条将没有样式。并且同样在 unistaller 中,样式不会影响窗框。请问有新版本或修复吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-22
相关资源
最近更新 更多