如何在 Delphi 中使用 RTTI 或 TypeInfo 获取枚举的有效范围
How can I get an enumeration's valid ranges using RTTI or TypeInfo in Delphi
我在测试项目中使用 RTTI 来评估枚举值,最常见的是对象的属性。如果枚举超出范围,我想显示类似于 Evaluate/Modify IDE Window 会显示的文本。像“(越界)255”之类的东西。
下面的示例代码使用 TypeInfo 在使用 GetEnumName
时将枚举之外的值的问题显示为访问冲突。任何使用 RTTI 或 TypeInfo 的解决方案都会对我有帮助,我只是不知道我的测试代码中的枚举类型
program Project60;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, TypInfo;
Type
TestEnum = (TestEnumA, TestEnumB, TestEnumC);
const
TestEnumUndefined = TestEnum(-1);
procedure WriteEnum(const ATypeInfo: PTypeInfo; const AOrdinal: Integer);
begin
WriteLn(Format('Ordinal: %d = "%s"', [AOrdinal, GetEnumName(ATypeInfo, AOrdinal)]));
end;
var
TestEnumTypeInfo: PTypeInfo;
begin
try
TestEnumTypeInfo := TypeInfo(TestEnum);
WriteEnum(TestEnumTypeInfo, Ord(TestEnumA));
WriteEnum(TestEnumTypeInfo, Ord(TestEnumB));
WriteEnum(TestEnumTypeInfo, Ord(TestEnumC));
WriteEnum(TestEnumTypeInfo, Ord(TestEnumUndefined)); //AV
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
ReadLn;
end.
使用GetTypeData()
to get more detailed information from a PTypeInfo
,例如:
procedure WriteEnum(const ATypeInfo: PTypeInfo; const AOrdinal: Integer);
var
LTypeData: PTypeData;
begin
LTypeData := GetTypeData(ATypeInfo);
if (AOrdinal >= LTypeData.MinValue) and (AOrdinal <= LTypeData.MaxValue) then
WriteLn(Format('Ordinal: %d = "%s"', [AOrdinal, GetEnumName(ATypeInfo, AOrdinal)]))
else
WriteLn(Format('Ordinal: %d (out of bound)', [AOrdinal]));
end;
我在测试项目中使用 RTTI 来评估枚举值,最常见的是对象的属性。如果枚举超出范围,我想显示类似于 Evaluate/Modify IDE Window 会显示的文本。像“(越界)255”之类的东西。
下面的示例代码使用 TypeInfo 在使用 GetEnumName
时将枚举之外的值的问题显示为访问冲突。任何使用 RTTI 或 TypeInfo 的解决方案都会对我有帮助,我只是不知道我的测试代码中的枚举类型
program Project60;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, TypInfo;
Type
TestEnum = (TestEnumA, TestEnumB, TestEnumC);
const
TestEnumUndefined = TestEnum(-1);
procedure WriteEnum(const ATypeInfo: PTypeInfo; const AOrdinal: Integer);
begin
WriteLn(Format('Ordinal: %d = "%s"', [AOrdinal, GetEnumName(ATypeInfo, AOrdinal)]));
end;
var
TestEnumTypeInfo: PTypeInfo;
begin
try
TestEnumTypeInfo := TypeInfo(TestEnum);
WriteEnum(TestEnumTypeInfo, Ord(TestEnumA));
WriteEnum(TestEnumTypeInfo, Ord(TestEnumB));
WriteEnum(TestEnumTypeInfo, Ord(TestEnumC));
WriteEnum(TestEnumTypeInfo, Ord(TestEnumUndefined)); //AV
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
ReadLn;
end.
使用GetTypeData()
to get more detailed information from a PTypeInfo
,例如:
procedure WriteEnum(const ATypeInfo: PTypeInfo; const AOrdinal: Integer);
var
LTypeData: PTypeData;
begin
LTypeData := GetTypeData(ATypeInfo);
if (AOrdinal >= LTypeData.MinValue) and (AOrdinal <= LTypeData.MaxValue) then
WriteLn(Format('Ordinal: %d = "%s"', [AOrdinal, GetEnumName(ATypeInfo, AOrdinal)]))
else
WriteLn(Format('Ordinal: %d (out of bound)', [AOrdinal]));
end;