在Delphi中循环遍历不规则枚举

时间:2010-11-09 10:36:36

标签: delphi loops enumeration

1)有没有人知道是否可以在Delphi(XE)中循环不规则枚举?

循环正常的枚举是可以的。来自Delphi Basics

var
  suit : (Hearts, Clubs, Diamonds, Spades);
begin
// Loop 3 times
For suit := Hearts to Diamonds do
   ShowMessage('Suit = '+IntToStr(Ord(suit)));
end;

但是,如果'suit'被声明为

var
  suit : (Hearts=1, Clubs, Diamonds=10, Spades);

它循环10次。并不令人惊讶,但我想循环3.我到目前为止找到的唯一解决方案是将枚举转换为集合并使用'for ... in'-loop,如delphi.about.com

所以,如果对问题1)的回答是否定的,那么:
2)如何从枚举转换为Delphi中的设置?

我使用它的上下文是编辑框(TEdit)的组件数组,它具有不规则的编号(edit1,edit5,edit7,edit3,...)。虽然可以对所有编辑框进行重新排序,但它删除了使用枚举作为一种灵活方式的原因,允许在枚举的中间添加一个编辑框。

6 个答案:

答案 0 :(得分:7)

我现在手头没有Delphi编译器,但我认为gabr的方法可以通过

显着改善
type
  TSuit = (Hearts = 1, Clubs, Diamonds = 10, Spades);

const
  Suits: array[0..3] of TSuit = (Hearts, Clubs, Diamonds, Spades);

谁知道,也许它甚至没有编译。

答案 1 :(得分:3)

type
  TSuit = (Hearts=1, Clubs, Diamonds=10, Spades);

var
  suit: TSuit;
  suitEnum: array [1..4] of TSuit;

//initialization
suitEnum[1] := Hearts;
suitEnum[2] := Clubs;
suitEnum[3] := Diamonds;
suitEnum[4] := Spades;

for suit in suitEnum do
  DoSomething(suit);

答案 2 :(得分:2)

我总是使用

var
  s: TSuit;
begin
  for s := Low(TSuit) to High(TSuit) do
    {something};
end;

答案 3 :(得分:0)

使用Ord(Hearts)循环到Ord(黑桃)?

答案 4 :(得分:0)

脏选项,对小枚举有用:

type
  TSuit = (Hearts = 1, Clubs, Diamonds = 10, Spades);
var
  Suit: TSuit;
begin
  for Suit in [Hearts, Clubs, Diamonds] do
    WriteLn(Ord(Suit));

在Delphi 2007中运行良好。不了解旧版本。请注意,使用for Suit in [Hearts..Diamonds] do会遇到与循环相同的问题。
顺便说一句,我使用WriteLn(),因为我在控制台应用程序中对此进行了测试。 : - )

答案 5 :(得分:0)

应该理解(通常不是)在你将硬序数赋值放入枚举的那一刻,它停止所有意图都是一个Pascalian枚举类型 - 它只是变成一个“常量包”,这是不一样的。这就是C程序员所说的枚举。但是,Pascalian枚举类型在所有标准中都是ORDINAL:它具有对基本操作ORD,PRED,SUCC有意义地响应的离散连续值。 C中的枚举不会这样做,一旦你强制将序数分开,Pascal中的枚举也不会。

这就是Delphi的RTTI在完成后基本上拒绝返回类型信息的原因。对于所有意图,类型本质上是tkUnknown,并且必须被视为编译时常量的“包”。这只是因为它仍然是一个口头服务,并且(有时是摇摇欲坠的)支持在集合中使用,人们被认为它应该仍然表现得像一个适当的枚举类型。最好只是理解它的真实含义:对C中的枚举值进行点头。避免混合编码隐喻!

如果你这样做,那么你的解决方案就变得很明显了:你使用枚举类型(一个合适的类型)来索引相应的CONSTANTS数组。然后你可以根据需要制作序数,并且枚举将其完整的RTTI定义保留为适当的枚举。因此:您的ENUMERATED TYPE包含正确的未更改的序数值。你可以通过使用字节=(1,3,8,22,99,无论如何)的枚举-ergo数组[MyEnums]索引常量数组来获得有趣的数字