首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么枚举类型会出现"type has no typeinfo“错误

为什么枚举类型会出现"type has no typeinfo“错误
EN

Stack Overflow用户
提问于 2009-09-14 09:40:33
回答 3查看 8.3K关注 0票数 23

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

代码语言:javascript
复制
  type
    TMyEnum = (
               meFirstValue = 1,
               meSecondValue,
               meThirdValue
              );

如果我调用TypeInfo(),例如作为GetEnumName(),调用的一部分,我会得到一个编译器错误:

代码语言:javascript
复制
  GetEnumName(TypeInfo(TMyEnum), Ord(aValue));

错误:"E2134:类型'TMyEnum‘没有类型信息“

为什么会这样呢?

我知道类只有在启用了$M编译器选项的情况下才会有typeinfo,或者(派生自一些曾经是的类,比如TPersistent),但我不认为对于枚举类型有typeinfo有任何特殊条件。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-09-14 09:42:12

类型信息不支持分配特定序数值的枚举,这些值会导致枚举成员具有与通常由编译器分配的值不同的序数值。

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

代码语言:javascript
复制
  type
    TMyEnum = (
                meNOTUSED1,   {= 0}
               meFirstValue,  {= 1} 
               meSecondValue,
               meThirdValue
              );

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

代码语言:javascript
复制
   TValidMyEnum = meFirstValue..meThirdValue;

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

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

代码语言:javascript
复制
  type
    TMyEnum = (
                meNOTUSED1,   {= 0}
               meFirstValue,  {= 1} 
               meSecondValue,
               meThirdValue,
                meNOTUSED2,
               meFinalValue   {= 5}
              );

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

代码语言:javascript
复制
  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
票数 23
EN

Stack Overflow用户

发布于 2009-09-14 10:00:47

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

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

票数 37
EN

Stack Overflow用户

发布于 2019-09-18 03:24:03

当您想要将枚举转换为特定值(并将其转换回来)时,我通常会创建一个数组const,每个枚举值都包含所需的值:

代码语言:javascript
复制
Const MyEnumValues: array[TMyEnum] of integer = (1,2,5);

这样,当枚举展开时,您会得到一个编译器错误,指出您缺少一个数组值。

请注意,当更改枚举的顺序时,必须相应地更改这些值。

要获取枚举值的‘value’,只需编写:

代码语言:javascript
复制
Value := MyEnumValues[myenum];

要获得基于‘value’的枚举值,只需循环遍历MyEnumValues的值:

代码语言:javascript
复制
Function GetEnumByValue(value:integer): TMyEnum;
Var
  myenum: TMyEnum;
Begin
  For myenum = low(TMyEnum) to high(TMyEnum) do
    If MyEnumValues[myenum] = value then
      exit(myenum);
  Raise exception.create(‘invalid value for tmyenum’);
End;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1420562

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档