代码之家  ›  专栏  ›  技术社区  ›  Deltics

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

  •  18
  • Deltics  · 技术社区  · 15 年前

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

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

    如果我打电话 类型信息() ,例如作为呼叫的一部分 获取枚举名称() ,我得到一个编译器错误:

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

    错误:“E2134:类型“tmyenum”没有typeinfo”

    为什么会这样?

    我知道类只有在用 百万美元 编译器选项已启用或(从某个类派生,例如 持续的 )但我认为没有任何特殊的条件可以为枚举类型提供typeinfo。

    2 回复  |  直到 15 年前
        1
  •  30
  •   Barry Kelly    15 年前

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

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

        2
  •  20
  •   Deltics    15 年前

    如果指定了特定的序号值,导致枚举成员具有不同于编译器通常分配的序号值,则枚举不支持类型信息。

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

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

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

       TValidMyEnum = meFirstValue..meThirdValue;
    

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

    如果枚举包含“间隙”,则子范围不够:

      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
    
    推荐文章