Arrays 在delphi中传递不同枚举类型的混合
我需要写一个程序,可以通过不同的枚举选择Arrays 在delphi中传递不同枚举类型的混合,arrays,delphi,enums,Arrays,Delphi,Enums,我需要写一个程序,可以通过不同的枚举选择 type TEnumOne = (eOneFlagOne, eOneFlagTwo); TEnumTwo = (eTwoFlagOne, eTwoFlagTwo); 该方法应采用不同的枚举: Process([eOneFlagOne, eTwoFlagTwo]); 我正试图这样实现它: // does not work! procedure Process(const Enums: array of Variant); var aValue;
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;
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;
那么,是否有一种类型而不是变体,我可以选择?或者这是一种不同的方法,我不明白?坦率地说,当你开始像这样弯曲你的语言时,通常意味着你的方法可能是错误的。(不总是,但通常)我很想听听你们想解决什么问题,因为也许有更好的设计方案 我们对您的问题所知甚少,我建议您创建两个具有不同签名的函数。
或
如果所需的逻辑分支彼此足够相似,那么可以使用enum类型作为泛型parm创建泛型方法(假设Delphi 2009或更高版本)
...
procedure Process<T>(const enumParam : T) // Add a generic constraint here as well
begin
...
end;
。。。
过程过程(const-enumParam:T)//在此处也添加一个泛型约束
开始
...
结束;
然而,在我看来,这两种不同的方法可能是最好的选择(或者完全是其他方法)符合pascal的优点 以下是您可能正在尝试的工作示例:
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];
另一种方法是将其保留为一个枚举:
TEnum = (eOneFlagOne, eOneFlagTwo, eTwoFlagOne, 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;
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;
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))]);
函数EnumToString(const-TypeInfo:pTypeInfo;Ix:Integer):字符串;
开始
结果:=GetEnumName(TypeInfo,ix);
结束;
过程过程(const Args:字符串数组);
变量
LIndex,ix:整数;
一号:十号;
第二名:十名;
开始
对于LIndex:=0到高(Args)是否开始
ix:=GetEnumValue(TypeInfo(TEnumOne),Args[LIndex]);
如果(ix-1),则
开始
EnumOne:=TEnumOne(ix);
//用一个做点什么
...
继续;
结束;
ix:=GetEnumValue(TypeInfo(TEnumTwo),Args[LIndex]);
如果(ix-1),则
开始
EnumTwo:=TEnumTwo(ix);
//用两个做点什么
...
继续;
结束;
...
等
结束;
结束;
进程([EnumToString(TypeInfo(TEnumOne)、Ord(TEnumOne.eOneFlagOne)),
EnumToString(TypeInfo(TEnumTwo),Ord(TEnumTwo.etwolflagtow2));
内存不足,如果我没弄错的话,您可以将枚举转换为整数,例如,I:=integer(eOneFlagOne)代码>和F:=TEnumOne(I)
在这种情况下,如果eOneFlagOne=0
那么eTwoFlagOne=0
也是如此。除非你想要更多的唯一ID,比如0,1/2,3而不是0,1/0,1,在这种情况下,我不知道。或者,作为替代,使用常量,例如,const E_ONE_FLAG_ONE=0;E_ONE_FLAG_TWO=1;E_2_标志_1=2;E_TWO_FLAG_TWO=3代码>等,并使用它们而不是枚举。顺便说一句,我肯定RRUZ要求的版本可能是因为较新的版本(如XE2)可能提供更简单的方法来实现这一点……您的设计听起来似乎有缺陷。我将重新考虑设计,而不是与语言抗争。值得一提的是,为了编写像aValue是TEnumOne这样的东西,您显然需要使用类而不是枚举。这些类可以包含枚举。我使用的是Delphi XE。问题是,枚举是由Rejects作为接口自动生成的。因此,我无法更改枚举的定义。要完成此操作,您需要TEnumOne=eOneFlagOne..eOneFlagTwo等,我无法更改或扩展enmus的类型定义。我也无法生成集。@FrancoisZbinden如果无法更改枚举的类型定义,并且如果无法生成集,则应更改Process函数,使其包含两个参数Process(EnumOneArray:Array of TEnumOne;EnumTwoArray:Array of Tenum2),然后检查两个数组中的条件。这只是重复Wouter的答案。除非你添加了一些新颖的东西,否则它只会变得杂乱无章使用一个集合(比如Wouter propose)对pascal语言来说比这样一个开放参数数组更自然、更有效。@ArnaudBouchez我同意。然而,这在实际中并不重要。只有当函数是某些需要高度优化的核心循环的一部分时,它才会起作用。