Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 在delphi中传递不同枚举类型的混合_Arrays_Delphi_Enums - Fatal编程技术网

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我同意。然而,这在实际中并不重要。只有当函数是某些需要高度优化的核心循环的一部分时,它才会起作用。