2

我知道如何从整数值中获取枚举值,并且我有这段代码

function GetEnumValue(intValue:integer):TMyType
begin
   if(ordValue >= Ord(Low(TMyType)))and(ordValue <= Ord(High(TMyType)))then 
      result :=TMyType(ordValue)
   else 
      raise Exception.Create('ordValue out of TMyType range');
end;

对于 TMyType 以外的许多枚举类型,我在很多地方都有类似上面的代码,我想将该代码封装到基类上的单个受保护代码中,以便继承的类可以使用它。

但我不知道如何概括 TMyType,所以我的代码可以检查它是正确的枚举类型还是其他类型的对象

我不知道枚举基类是什么(例如所有对象类型的 TObject 或所有 VCL 类型的 TControl),然后我可以像该代码一样检查

4

1 回答 1

4

枚举类型没有基类型,就像 TObject 是类的基。

如果您有一个支持泛型的 Delphi 版本,您可以使用以下帮助器将泛型从序数值转换为枚举值。

uses
  System.SysUtils,TypInfo;

Type
  TEnumHelp<TEnum> = record
  type
    ETEnumHelpError = class(Exception);
    class function Cast(const Value: Integer): TEnum; static;
  end;

class function TEnumHelp<TEnum>.Cast(const Value: Integer): TEnum;
var
  typeInf  : PTypeInfo;
  typeData : PTypeData;
begin
  typeInf := PTypeInfo(TypeInfo(TEnum));
  if (typeInf = nil) or (typeInf^.Kind <> tkEnumeration) then
    raise ETEnumHelpError.Create('Not an enumeration type');
  typeData := GetTypeData(typeInf);
  if (Value < typeData^.MinValue) then
    raise ETEnumHelpError.CreateFmt('%d is below min value [%d]',[Value,typeData^.MinValue])
  else
  if (Value > typeData^.MaxValue) then
    raise ETEnumHelpError.CreateFmt('%d is above max value [%d]',[Value,typeData^.MaxValue]);
  case Sizeof(TEnum) of
    1: pByte(@Result)^ := Value;
    2: pWord(@Result)^ := Value;
    4: pCardinal(@Result)^ := Value;
  end;
end;

例子:

Type
  TestEnum = (aA,bB,cC);

var
  e : TestEnum;
...
e := TEnumHelp<TestEnum>.Cast(2);  // e = cC

有一个限制:

不连续或不以零开头的枚举没有RTTITypeInfo 信息。见RTTI properties not returned for fixed enumerations: is it a bug?

于 2013-05-08T06:34:45.603 回答