Del*_*ics 19 delphi enums rtti typeinfo
我已经声明了以下枚举类型,其中我希望第一个成员的序数值为1(一)而不是通常的0(零):
type
TMyEnum = (
meFirstValue = 1,
meSecondValue,
meThirdValue
);
Run Code Online (Sandbox Code Playgroud)
如果我调用TypeInfo(),例如作为对GetEnumName()的调用的一部分,我得到一个编译器错误:
GetEnumName(TypeInfo(TMyEnum), Ord(aValue));
Run Code Online (Sandbox Code Playgroud)
错误:"E2134:类型'TMyEnum'没有typeinfo"
为什么是这样?
我知道,类只有所属类别,如果它们与编译$ M启用编译器选项,或者(在某些类是,如获得TPersistent,但我不认为有具有所属类别的枚举类型的任何特殊情况).
Bar*_*lly 32
不以零开头的不连续枚举和枚举没有typeinfo.对于要实现的typeinfo,由于向后兼容性问题,它需要采用与现有tkEnumeration不同的格式.
我考虑推行tkDiscontiguousEnumeration(或可能更好的命名部件)德尔福2010年,但它的好处似乎是小考虑到其相对稀缺性和在列举的困难 - 你如何有效编码范围?某些编码对某些情况更好,对其他情况则更糟.
Del*_*ics 21
枚举不支持类型信息,其中分配了特定的序数值,导致枚举成员的序数值与编译器通常分配的序数值不同.
如果特定值是必要的或期望的,则必须插入"未使用的"枚举成员以根据需要"填充"枚举.例如(仅用于强调的附加缩进):
type
TMyEnum = (
meNOTUSED1, {= 0}
meFirstValue, {= 1}
meSecondValue,
meThirdValue
);
Run Code Online (Sandbox Code Playgroud)
然后可以使用子范围"过滤"未使用的初始值:
TValidMyEnum = meFirstValue..meThirdValue;
Run Code Online (Sandbox Code Playgroud)
虽然您可能希望考虑重命名原始枚举类型,以便您的子范围类型可以在整个项目中使用.
如果枚举包含"间隙",则子范围是不够的:
type
TMyEnum = (
meNOTUSED1, {= 0}
meFirstValue, {= 1}
meSecondValue,
meThirdValue,
meNOTUSED2,
meFinalValue {= 5}
);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,没有简单的方法来扩展编译时范围检查以排除未使用的成员,但是几种集合类型将简化实现任何必要的运行时检查的业务:
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
Run Code Online (Sandbox Code Playgroud)