Reputation: 317
I know how to get enum value from integer value, and I have this code
function GetEnumValue(intValue:integer):TMyType
begin
if(ordValue >= Ord(Low(TMyType)))and(ordValue <= Ord(High(TMyType)))then
result :=TMyType(ordValue)
else
raise Exception.Create('ordValue out of TMyType range');
end;
I have similiar code like above in many place for many enum type other than TMyType, I want encapsulate that code to single protected code on base class, so inherited class can use it.
but I dont know how to generalize TMyType, so my code can check if it right enum type or another type object
I cant have a clue what a enum base class (like TObject for all of object type or TControl for all of VCL type), then I can check like that code
Upvotes: 2
Views: 5402
Reputation: 34909
There is no such thing as a base type for an enumeration type, like TObject is the base for classes.
If you have a Delphi version that supports generics, you can use following helper to make a generic cast from an ordinal value to an enumeration value.
uses
System.SysUtils,TypInfo;
Type
TEnumHelp<TEnum> = record
type
ETEnumHelpError = class(Exception);
class function Cast(const Value: Integer): TEnum; static;
end;
class function TEnumHelp<TEnum>.Cast(const Value: Integer): TEnum;
var
typeInf : PTypeInfo;
typeData : PTypeData;
begin
typeInf := PTypeInfo(TypeInfo(TEnum));
if (typeInf = nil) or (typeInf^.Kind <> tkEnumeration) then
raise ETEnumHelpError.Create('Not an enumeration type');
typeData := GetTypeData(typeInf);
if (Value < typeData^.MinValue) then
raise ETEnumHelpError.CreateFmt('%d is below min value [%d]',[Value,typeData^.MinValue])
else
if (Value > typeData^.MaxValue) then
raise ETEnumHelpError.CreateFmt('%d is above max value [%d]',[Value,typeData^.MaxValue]);
case Sizeof(TEnum) of
1: pByte(@Result)^ := Value;
2: pWord(@Result)^ := Value;
4: pCardinal(@Result)^ := Value;
end;
end;
Example:
Type
TestEnum = (aA,bB,cC);
var
e : TestEnum;
...
e := TEnumHelp<TestEnum>.Cast(2); // e = cC
There is one limitation:
Enumerations that are discontiguous or does not start with zero,
have no RTTI
TypeInfo information. See RTTI properties not returned for fixed enumerations: is it a bug?
.
Upvotes: 4