我在枚举器类型上定义了InRange
函数。如果传递的整数参数可以转换为枚举器类型,则该函数应返回True
。
TMyEnum = (eA, eB);
TMyEnumHelper = record helper for TMyEnum
class function InRange(AValue : integer) : Boolean; static;
end;
...
class function TMyEnumHelper.InRange(AValue : integer) : Boolean;
begin
Result :=
(AValue >= Low(TMyEnum)) and
(AValue <= High(TMyEnum));
end;
在编译时,在(AValue >= Low(TMyEnum))
行,出现以下错误:
[[dcc32错误] Unit1.pas(34):E2008不兼容类型
我做了一些测试,但我真的不明白怎么了...即:
AValue
函数的InRange
参数类型切换为Byte
,ShortInt
,Word
,SmallInt
,LongWord
,Cardinal
,LongInt
,Integer
和Int64
,但在编译时会引发相同的错误。TMyEnum = 0..1;
,则编译时不会出错。您不能直接将枚举值与整数进行比较。您必须将枚举值转换为整数值才能进行比较:
class function TMyEnumHelper.InRange(AValue : integer) : Boolean;
begin
Result :=
(AValue >= Ord(Low(TMyEnum))) and
(AValue <= Ord(High(TMyEnum)));
end;
请注意添加的“ ord”强制转换,它将其“ parameter”(括号内的表达式)转换为整数值。
您的原因
TMyEnum = 0..1;
有用的是,这不是枚举,而是整数子范围,因此TMyEnum的基本类型是整数而不是枚举。
您还可以使用泛型而不是辅助函数来使InRange
支持所有枚举类型:
uses
SysUtils, TypInfo;
type
TMyEnum1 = (me1A, me1B);
TMyEnum2 = (me2A, me2B, me2C);
TMyEnum3 = (me3A = 1, me3B = 3);
TEnum = class
class function InRange<T>(const AValue: Integer): Boolean; static;
end;
{ TEnum }
class function TEnum.InRange<T>(const AValue: Integer): Boolean;
var
TI: PTypeInfo;
TD: PTypeData;
begin
TI := TypeInfo(T);
if not Assigned(TI) then
raise Exception.Create('InRange does not support discontinuous enumerations.');
if TI^.Kind <> tkEnumeration then
raise Exception.Create('InRange only supports enumeration types.');
TD := GetTypeData(TI);
Result :=
(AValue >= TD^.MinValue) and
(AValue<=TD^.MaxValue);
end;
begin
try
Writeln(BoolToStr(TEnum.InRange<TMyEnum1>(2), true));
Writeln(BoolToStr(TEnum.InRange<TMyEnum2>(2), true));
Writeln(BoolToStr(TEnum.InRange<TMyEnum3>(2), true));
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
产生:
假真正例外:InRange不支持不连续的枚举。
注意:如果为True
实现,则当前方法将为AValue
= 2返回TMyEnum3
。