Delphi pitfalls: Enumerated types and for loops

Not all for loops are created equal.

Consider
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:

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.

The above code yields

Declared: TEnum = (plough, foo, bar, wtf)
Test order: [wtf, plough, bar, foo]

Looping an Enum Set
plough
foo
bar
wtf

Looping an Enum Array
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.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.