我已经声明了以下枚举类型,其中我希望第一个成员的序数值为1(一)而不是通常的0(零):

  type
    TMyEnum = (
               meFirstValue = 1,
               meSecondValue,
               meThirdValue
              );

如果我拨打 TypeInfo(),例如作为对 GetEnumName()的调用的一部分,我收到编译器错误:

  GetEnumName(TypeInfo(TMyEnum), Ord(aValue));

错误:“E2134:类型'TMyEnum'没有typeinfo"

为什么会这样?

我知道只有在启用 $ M 编译器选项的情况下编译类或者(从某些类派生,例如 TPersistent )时类只有typeinfo但是我没想到为enum类型设置typeinfo有任何特殊条件。

有帮助吗?

解决方案 2

枚举不支持类型信息,其中指定的特定序数值导致枚举成员的序数值与编译器通常分配的序数值不同。

如果特定值是必要的或期望的,则“未使用”枚举成员必须插入“填充”根据需要枚举。例如(仅用于强调的附加缩进):

  type
    TMyEnum = (
                meNOTUSED1,   {= 0}
               meFirstValue,  {= 1} 
               meSecondValue,
               meThirdValue
              );

然后可以使用子范围来“过滤”输出未使用的初始值:

   TValidMyEnum = meFirstValue..meThirdValue;

虽然您可能希望考虑重命名原始枚举类型,以便在整个项目中使用您的子范围类型。

如果枚举包含“gap”,则子范围是不够的:

  type
    TMyEnum = (
                meNOTUSED1,   {= 0}
               meFirstValue,  {= 1} 
               meSecondValue,
               meThirdValue,
                meNOTUSED2,
               meFinalValue   {= 5}
              );

在这种情况下,没有简单的方法来扩展编译时范围检查以排除未使用的成员,但是几种集合类型将简化实现任何必要的运行时检查的业务:

  type
    TMyEnums = set of TMyEnum;

  const
    meNOTUSED      = [meUNUSED1, meUNUSED2]; //  .. etc as required
    meValidValues  = [Low(TMyEnum)..High(TMyEnum)] - meNOTUSED;


  if NOT (aValue in meValidValues) then
     // etc

其他提示

不以零开头的不连续枚举和枚举没有typeinfo。对于要实现的typeinfo,由于向后兼容性问题,它需要采用与现有tkEnumeration不同的格式。

我考虑过为Delphi 2010实现一个tkDiscontiguousEnumeration(或者可能更好的命名成员),但考虑到它们的相对稀缺性和枚举的困难,它的好处似乎很小 - 你如何有效地编码范围?有些编码对某些情况更好,对其他情况则更糟。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top