Articles Delphi pitfalls: Enumerated types and for loops by Lars Fosdal

emailx45

Social Engineer
Joined
May 5, 2008
Messages
2,387
Reaction score
2,149
Delphi pitfalls: Enumerated types and for loops
Lars Fosdal - 18/Feb/2019
[SHOWTOGROUPS=4,20]
Not all for loops are created equal.

Consider:
Code:
for x in [value1, value2, value3]

You would expect to see x vary in the order of the values in the list.

However – if x and the values are of an enumerated type, looping the “list”
does NOT loop in the apparent order of the constant, but in the order of the enumerated type declaration, such as it would for any set.

An example:

Code:
  program EnumArrayvsEnumSet;
{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

type
  TEnum = (plough, foo, bar, wtf);

procedure Output(const aEnum: TEnum);
begin
  case aEnum of
    wtf:
      Writeln('wtf');
    plough:
      Writeln('plough');
    bar:
      Writeln('bar');
    foo:
      Writeln('foo');
  else
    Writeln('Missed one!');
  end;
end;

procedure TestEnumSet;
var
  enum: TEnum;
begin
  for enum in [wtf, plough, bar, foo] do
    Output(enum);
end;

procedure TestEnumArray;
var
  enum     : TEnum;
  enumArray: TArray<TEnum>;
begin
  enumArray := [wtf, plough, bar, foo];
  for enum in enumArray do
    Output(enum);
end;

begin
  try
    try
      Writeln('Declared: TEnum = (plough, foo, bar, wtf)');
      Writeln('Test order: [wtf, plough, bar, foo]');
      Writeln;
      Writeln('Looping an Enum Set');
      TestEnumSet;
      Writeln;
      Writeln('Looping an Enum Array');
      TestEnumArray;
    except
      on E: Exception do
        Writeln(E.ClassName, ': ', E.Message);
    end;
  finally
    Writeln;
    Write('Press Enter:');
    Readln;
  end;

end.


view rawEnumArrayvsEnumSet.dpr hosted by GitHub

The above code yields
Code:
Declared: TEnum = (plough, foo, bar, wtf)
Test order: [wtf, plough, bar, foo]

Looping an Enum Set
Code:
plough
foo
bar
wtf

Looping an Enum Array
Code:
wtf
plough
bar
foo

Press Enter:

This can be easy to miss, so if loop order is important – make sure you code your enums into an actual array and do not leave them as a set.

[/SHOWTOGROUPS]
 
Top