I need to write a procedure where can pass different enum selections.
type
TEnumOne = (eOneFlagOne, eOneFlagTwo);
TEnumTwo = (eTwoFlagOne, eTwoFlagTwo);
The method should take different enums:
Process([eOneFlagOne, eTwoFlagTwo]);
I'm trying to implement it like this:
// does not work!
procedure Process(const Enums: array of Variant);
var aValue; Variant
begin
for aValue in Enums do
begin
// of course, can't work...
if aValue is TEnumOne then
end;
end;
So, is there a type instead of Variant, I can choose? Or is the a different approach, I dont' see?
Meet the beauty of pascal.
Here's a working example of what you're probably trying to do:
program Project34; {$APPTYPE CONSOLE}
type
TEnum=(eOneFlagOne,eOneFlagTwo,eTwoFlagOne,eTwoFlagTwo);
TEnumSet=set of TEnum;
const
cEnumOne=[eOneFlagOne,eOneFlagTwo];
cEnumTwo=[eTwoFlagOne,eTwoFlagTwo];
procedure Process(const Enums: TEnumSEt);
var e:TEnum;
begin
for e in Enums do
WriteLn(ord(e));
end;
begin
Process([eOneFlagOne, eTwoFlagTwo]);
Process(cEnumOne);
Process(cEnumTwo);
end.
Note that you can also declare the constants like this. Maybe that's clearer:
const
cEnumOne:TEnumSet=[eOneFlagOne,eOneFlagTwo];
cEnumTwo:TEnumSet=[eTwoFlagOne,eTwoFlagTwo];
To be blunt, when you start trying to bend your language like this, it usually means that your approach is probably wrong. (not always, but usually) I'd be interested to hear what problem you are trying to solve, as maybe there is a better design option.
With what little we know about your problem, I would suggest that either you create 2 functions with the different signatures.
Or
if the required logic branch is similar enough to each other, then you could create a Generic method (assuming Delphi 2009 or higher) using the enum type as your generic parm.
...
procedure Process<T>(const enumParam : T) // Add a generic constraint here as well
begin
...
end;
Seems likely to me however, that the 2 different methods would be the likely best option (or something else entirely)
RRUZ deleted his answer, here is a reworked version with type safety. RTTI is used to identify the different enum constants.
function EnumToString(const TypeInfo : pTypeInfo; Ix : Integer) : string;
begin
Result := GetEnumName(TypeInfo, ix);
end;
procedure Process( const Args : array of string);
var
LIndex,ix : integer;
EnumOne : TEnumOne;
EnumTwo : TEnumTwo;
begin
for LIndex := 0 to High(Args) do begin
ix := GetEnumValue( TypeInfo(TEnumOne), Args[LIndex]);
if (ix <> -1) then
begin
EnumOne := TEnumOne( ix);
// do something with EnumOne
...
continue;
end;
ix := GetEnumValue( TypeInfo(TEnumTwo), Args[LIndex]);
if (ix <> -1) then
begin
EnumTwo := TEnumTwo( ix);
// do something with EnumTwo
...
continue;
end;
...
etc
end;
end;
Process( [EnumToString(TypeInfo(TEnumOne),Ord(TEnumOne.eOneFlagOne)),
EnumToString(TypeInfo(TEnumTwo),Ord(TEnumTwo.eTwoFlagTwo))]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With