progging - To wander about and beg; to seek food or other supplies by low arts; to seek for advantage by mean shift or tricks.
progging - Programmer slang for writing computer code.

fredag 19. august 2011

Implementing enumerators on delphi records

Implementing enumerators are pretty easy in Delphi and many articles exist on the topic:


For some reason, I had a simple record to hold a small array of another type where the use was to loop round and do some action on every type. I used a record instead of a class to avoid the Create/Destroy and since it was just used to hold some simple data.
The first thing I noticed was that the Enumerator had to be a class (and not a record as recommended here) because I could not have a forward declaration to a record. Since my "list type" was a record I had to "forward declare" the enumerator before the record type.

  TLongTrendFieldsEnumerator = class;

  TLongTrendFields = record
    { Private declarations }
    PlotList: array[0..MAX_LONG_TREND_FIELDS] of TPlot;
    function GetItem(index : Integer) : TPlot;
    { Public declarations }
    property Items[i:Integer] : TPlot read GetItem; default;
    function GetEnumerator: TLongTrendFieldsEnumerator;

The next thing to think of is that the list type is a record, so we don't want to copy the instance when we pass it to the enumerator. So we use pointer instead, beginning with declaring a pointer type

  TLongTrendFieldsEnumerator = class;

  TLongTrendFieldsPointer = ^TLongTrendFields;
  TLongTrendFields = record
So then the enumerator class will look like this:

  TLongTrendFieldsEnumerator = class
    index: Integer;
    fields: TLongTrendFieldsPointer;
    constructor Create(aFields: TLongTrendFieldsPointer);
    function MoveNext: Boolean;
    function GetCurrent: TPlot;
    property Current: TPlot read GetCurrent;
The only difference in the implementation is that when the list type creates the enumerator it has to send a reference/pointer to the enumerator's constructor.
function TLongTrendFields.GetEnumerator: TLongTrendFieldsEnumerator;
  Result := TLongTrendFieldsEnumerator.Create(@Self);
The rest of the implementation is identical to the other examples (without pointers) thanks to Delphi's nice pointer syntax handling!

Ingen kommentarer:

Legg inn en kommentar