如何使用Delphi 6迭代初始化枚举类型并避免;“禁止入内”;错误?

如何使用Delphi 6迭代初始化枚举类型并避免;“禁止入内”;错误?,delphi,types,for-loop,loops,enumerate,Delphi,Types,For Loop,Loops,Enumerate,我使用的是Delphi6 Professional。我正在与一个DLL库交互,该库声明枚举类型,如下所示: TExtDllEnum = (ENUM1 = $0, ENUM2 = $1, ENUM3 = $2, ENUM4 = $4, ENUM5 = $8, ENUM6 = $10); var e: TExtDllEnum; begin for e := Low(TExtToDllEnum) to High(TExtToDllEnum) do ... // More co

我使用的是Delphi6 Professional。我正在与一个DLL库交互,该库声明枚举类型,如下所示:

TExtDllEnum = (ENUM1 = $0, ENUM2 = $1, ENUM3 = $2, ENUM4 = $4, ENUM5 = $8, ENUM6 = $10);
var
    e: TExtDllEnum;
begin
    for e := Low(TExtToDllEnum) to High(TExtToDllEnum) do
    ... // More code
end;
正如您所看到的,初始化值不是连续的。如果我尝试使用for循环迭代该类型,如下所示:

TExtDllEnum = (ENUM1 = $0, ENUM2 = $1, ENUM3 = $2, ENUM4 = $4, ENUM5 = $8, ENUM6 = $10);
var
    e: TExtDllEnum;
begin
    for e := Low(TExtToDllEnum) to High(TExtToDllEnum) do
    ... // More code
end;
Delphi仍然会在每次循环调用时将e增加1,从而为e创建非枚举类型成员的数值(例如,“3”),并导致“越界”错误。如何在只为枚举类型生成有效值的for循环中迭代枚举类型


谢谢。

据我记忆所及,没有办法按你想要的方式迭代。如果枚举不经常更改,一个解决方法可能是声明一个“索引数组”,它可以让您以想要的方式进行迭代。诀窍在于,您不会迭代枚举,而是迭代一个索引,您可以将该索引“转换”为枚举中的有效元素:

我想我可以用代码更好地解释这个想法:

const
  ExtDllEnumElements = 6;
  EnumIndexArray: array[0..ExtDllEnumElements - 1] of TExtDllEnum = (ENUM1, ENUM2, ENUM3, ENUM4, ENUM5, ENUM6);
var
  I: Integer;
begin
  for I := Low(EnumIndexArray) to High(EnumIndexArray) do
    WhateverYouWantWith(EnumIndexArray[I]);
end;
你不能

如果值是二进制加权的,请尝试使用如下while循环

var
    e: TExtDllEnum;
begin
    e := 0;
    While e <= High(TExtToDllEnum) do
    begin
        ... // More code
        e := Power(2, e);
    end;

end;
var
e:纺织业;
开始
e:=0;

当您定义枚举时,e

TExtDllEnum = (ENUM1 = $0, ENUM2 = $1, ENUM3 = $2, ENUM4 = $4, ENUM5 = $8, ENUM6 = $10);
您实际上定义了由17($10+1)个可能值组成的枚举类型。 就是

有很多方法可以只在指定的枚举常量上实现迭代(请参见其他答案),但您执行迭代的方式是对17个值进行迭代,这是无法更改的

下面是另一个迭代示例,它使用了除ENUM1之外的所有ENUMx值都是2的幂这一事实:

type
  TExtDllEnum = (ENUM1 = $0, ENUM2 = $1, ENUM3 = $2,
                 ENUM4 = $4, ENUM5 = $8, ENUM6 = $10);
var
    e: TExtDllEnum;

begin
  e:= Low(TExtDllEnum);
  repeat
    [..]
    if e = ENUM1 then e:= ENUM2
    else if e = High(TExtDllEnum) then Break
    else e:= e shl 1;
  until False;
end;

通过定义一组常量

type
  TExtDllEnum = (ENUM1 = $0, ENUM2 = $1, ENUM3 = $2, ENUM4 = $4, ENUM5 = $8, ENUM6 = $10);

const
  CExtDllEnumSet = [ENUM1, ENUM2, ENUM3, ENUM4, ENUM5, ENUM6];


var
  e: TExtDllEnum;
begin
  e := Low(TExtDllEnum);
  while e <= High(TExtDllEnum) do
  begin
    if e in CExtDllEnumSet then 
      WriteLn(Ord(e));

    Inc(e);
  end;

  ReadLn;
end.
类型
textdLenum=(ENUM1=$0,ENUM2=$1,ENUM3=$2,ENUM4=$4,ENUM5=$8,ENUM6=$10);
常数
CExtDllEnumSet=[ENUM1、ENUM2、ENUM3、ENUM4、ENUM5、ENUM6];
变量
e:纺织业;
开始
e:=低(textdlenum);
而e