我声明了以下枚举类型,其中我希望第一个成员的序数值为1(1),而不是通常的0(零):
type
TMyEnum = (
meFirstValue = 1,
meSecondValue,
meThirdValue
);如果我调用TypeInfo(),例如作为GetEnumName(),调用的一部分,我会得到一个编译器错误:
GetEnumName(TypeInfo(TMyEnum), Ord(aValue));错误:"E2134:类型'TMyEnum‘没有类型信息“
为什么会这样呢?
我知道类只有在启用了$M编译器选项的情况下才会有typeinfo,或者(派生自一些曾经是的类,比如TPersistent),但我不认为对于枚举类型有typeinfo有任何特殊条件。
发布于 2009-09-14 09:42:12
类型信息不支持分配特定序数值的枚举,这些值会导致枚举成员具有与通常由编译器分配的值不同的序数值。
如果特定值是必需的或需要的,则必须根据需要插入“未使用的”枚举成员来“填充”枚举。例如(仅用于强调的额外缩进):
type
TMyEnum = (
meNOTUSED1, {= 0}
meFirstValue, {= 1}
meSecondValue,
meThirdValue
);然后,可以使用子范围来“过滤”出未使用的初始值:
TValidMyEnum = meFirstValue..meThirdValue;尽管您可能希望考虑重命名原始枚举类型,以便可以在整个项目中使用您的子范围类型。
如果枚举包含“间隔”,子范围是不够的:
type
TMyEnum = (
meNOTUSED1, {= 0}
meFirstValue, {= 1}
meSecondValue,
meThirdValue,
meNOTUSED2,
meFinalValue {= 5}
);在这种情况下,没有简单的方法来扩展编译时范围检查以排除未使用的成员,但几个set类型将简化实现任何必要的运行时检查的业务:
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发布于 2009-09-14 10:00:47
不连续的枚举和不是从零开始的枚举没有typeinfo。对于要实现的typeinfo,由于向后兼容性问题,它需要采用与现有tkEnumeration不同的格式。
我考虑过为Delphi2010实现一个tkDiscontiguousEnumeration (或者更好的命名成员),但考虑到它们的相对稀缺性和枚举的困难,好处似乎很小-如何有效地编码范围?有些编码在某些情况下更好,在其他情况下更差。
发布于 2019-09-18 03:24:03
当您想要将枚举转换为特定值(并将其转换回来)时,我通常会创建一个数组const,每个枚举值都包含所需的值:
Const MyEnumValues: array[TMyEnum] of integer = (1,2,5);这样,当枚举展开时,您会得到一个编译器错误,指出您缺少一个数组值。
请注意,当更改枚举的顺序时,必须相应地更改这些值。
要获取枚举值的‘value’,只需编写:
Value := MyEnumValues[myenum];要获得基于‘value’的枚举值,只需循环遍历MyEnumValues的值:
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;https://stackoverflow.com/questions/1420562
复制相似问题