我需要编写一个可以传递不同枚举选择的过程。
type
TEnumOne = (eOneFlagOne, eOneFlagTwo);
TEnumTwo = (eTwoFlagOne, eTwoFlagTwo);
该方法应采用不同的枚举:
Process([eOneFlagOne, eTwoFlagTwo]);
我正试图像这样实现它:
// 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;
那么,有没有一种类型而不是Variant,我可以选择吗?或者是一种不同的方法,我不看?
答案 0 :(得分:10)
满足帕斯卡的美丽。
以下是您可能尝试做的一个工作示例:
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.
请注意,您也可以像这样声明常量。也许这更清楚:
const
cEnumOne:TEnumSet=[eOneFlagOne,eOneFlagTwo];
cEnumTwo:TEnumSet=[eTwoFlagOne,eTwoFlagTwo];
答案 1 :(得分:4)
说实话,当你开始尝试像这样弯曲你的语言时,通常意味着你的方法可能是错误的。 (并不总是,但通常)我很想知道你想要解决的问题,也许有更好的设计方案。
由于我们对您的问题知之甚少,我建议您使用不同的签名创建2个函数。
或者
如果所需的逻辑分支彼此足够相似,那么您可以使用枚举类型作为通用parm创建一个Generic方法(假设Delphi 2009或更高版本)。
...
procedure Process<T>(const enumParam : T) // Add a generic constraint here as well
begin
...
end;
然而,在我看来,这两种不同的方法可能是最好的选择(或其他完全不同的选择)
答案 2 :(得分:1)
RRUZ删除了他的回答,这是一个带有类型安全的重写版本。 RTTI用于识别不同的枚举常量。
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))]);
答案 3 :(得分:0)
另一种方法是将其保留为一个枚举:
TEnum = (eOneFlagOne, eOneFlagTwo, eTwoFlagOne, eTwoFlagTwo);
Process函数看起来像这样:
procedure Process(Enums: Array of TEnum);
var
aValue: TEnum;
begin
for aValue in Enums do
begin
if aValue in [eOneFlagOne, eOneFlagTwo] then
// Handle the eOne enums
else if aValue in [eTwoFlagOne, eTwoFlagTwo] then
// Handle the eTwo enums
end;
end;