Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 937323
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T21:27:35+00:00 2026-05-15T21:27:35+00:00

Using Delphi 2010, let’s say I’ve got a class declared like this: TMyList =

  • 0

Using Delphi 2010, let’s say I’ve got a class declared like this:

TMyList = TList<TMyObject>

For this list Delphi kindly provides us with an enumerator, so we can write this:

var L:TMyList;
    E:TMyObject;
begin
  for E in L do ;
end;

The trouble is, I’d like to write this:

var L:TMyList;
    E:TMyObject;
begin
  for E in L.GetEnumerator('123') do ;
end;

That is, I want the ability to provide multiple enumerators for the same list, using some criteria. Unfortunately the implementation of for X in Z requires the presence of a function Z.GetEnumerator, with no parameters, that returns the given enumerator! To circumvent this problem I’m defining an interface that implements the “GetEnumerator” function, then I implement a class that implements the interface and finally I write a function on TMyList that returns the interface! And I’m returning an interface because I don’t want to be bothered with manually freeing the very simple class… Any way, this requires a LOT of typing. Here’s how this would look like:

TMyList = class(TList<TMyObject>)
protected

  // Simple enumerator; Gets access to the "root" list
  TSimpleEnumerator = class
  protected
  public
    constructor Create(aList:TList<TMyObject>; FilterValue:Integer);

    function MoveNext:Boolean; // This is where filtering happens
    property Current:TTipElement;
  end;

  // Interface that will create the TSimpleEnumerator. Want this
  // to be an interface so it will free itself.
  ISimpleEnumeratorFactory = interface
    function GetEnumerator:TSimpleEnumerator;
  end;

  // Class that implements the ISimpleEnumeratorFactory
  TSimpleEnumeratorFactory = class(TInterfacedObject, ISimpleEnumeratorFactory)
    function GetEnumerator:TSimpleEnumerator;
  end;

public
  function FilteredEnum(X:Integer):ISimpleEnumeratorFactory;
end;

Using this I can finally write:

var L:TMyList;
    E:TMyObject;
begin
  for E in L.FilteredEnum(7) do ;
end;

Do you know a better way of doing this? Maybe Delphi does support a way of calling GetEnumerator with a parameter directly?

Later Edit:

I decided to use Robert Love’s idea of implementing the enumerator using anonymous methods and using gabr’s “record” factory to save yet an other class. This allows me to create a brand new enumerator, complete with code, using just a few lines of code in a function, no new class declaration required.

Here’s how my generic enumerator is declared, in a library unit:

TEnumGenericMoveNext<T> = reference to function: Boolean;
TEnumGenericCurrent<T> = reference to function: T;

TEnumGenericAnonim<T> = class
protected
  FEnumGenericMoveNext:TEnumGenericMoveNext<T>;
  FEnumGenericCurrent:TEnumGenericCurrent<T>;
  function GetCurrent:T;
public
  constructor Create(EnumGenericMoveNext:TEnumGenericMoveNext<T>; EnumGenericCurrent:TEnumGenericCurrent<T>);

  function MoveNext:Boolean;
  property Current:T read GetCurrent;
end;

TGenericAnonEnumFactory<T> = record
public
  FEnumGenericMoveNext:TEnumGenericMoveNext<T>;
  FEnumGenericCurrent:TEnumGenericCurrent<T>;
  constructor Create(EnumGenericMoveNext:TEnumGenericMoveNext<T>;   EnumGenericCurrent:TEnumGenericCurrent<T>);
  function GetEnumerator:TEnumGenericAnonim<T>;
end;

And here’s a way to use it. On any class I can add a function like this (and I’m intentionally creating an enumerator that doesn’t use a List<T> to show the power of this concept):

type Form1 = class(TForm)
protected
  function Numbers(From, To:Integer):TGenericAnonEnumFactory<Integer>;  
end;

// This is all that's needed to implement an enumerator!
function Form1.Numbers(From, To:Integer):TGenericAnonEnumFactory<Integer>;
var Current:Integer;
begin
  Current := From - 1;
  Result := TGenericAnonEnumFactory<Integer>.Create(
    // This is the MoveNext implementation
    function :Boolean
    begin
      Inc(Current);
      Result := Current <= To;
    end
    ,
    // This is the GetCurrent implementation
    function :Integer
    begin
      Result := Current;
    end
  );
end;

And here’s how I’d use this new enumerator:

procedure Form1.Button1Click(Sender: TObject);
var N:Integer;
begin
  for N in Numbers(3,10) do
    Memo1.Lines.Add(IntToStr(N));
end;
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-15T21:27:35+00:00Added an answer on May 15, 2026 at 9:27 pm

    Delphi For in loop support requires on of the following: (From the Docs)

    • Primitive types that the compiler
      recognizes, such as arrays, sets or
      strings
    • Types that implement
      IEnumerable
    • Types that implement the
      GetEnumerator pattern as documented
      in the Delphi Language Guide

    If you look at Generics.Collections.pas you will find the implementation for TDictionary<TKey,TValue> where it has three enumerators for TKey, TValue, and TPair<TKey,TValue> types. Embarcadero shows that they have used verbose implementation.

    You could do something like this:

    unit Generics.AnonEnum;
    interface
    uses
     SysUtils,
     Generics.Defaults,
     Generics.Collections;
    
    type
    
      TAnonEnumerator<T> = class(TEnumerator<T>)
      protected
        FGetCurrent : TFunc<TAnonEnumerator<T>,T>;
        FMoveNext : TFunc<TAnonEnumerator<T>,Boolean>;
        function DoGetCurrent: T; override;
        function DoMoveNext: Boolean; override;
      public
        Constructor Create(aGetCurrent : TFunc<TAnonEnumerator<T>,T>;
                           aMoveNext : TFunc<TAnonEnumerator<T>,Boolean>);
      end;
    
      TAnonEnumerable<T> = class(TEnumerable<T>)
      protected
        FGetCurrent : TFunc<TAnonEnumerator<T>,T>;
        FMoveNext : TFunc<TAnonEnumerator<T>,Boolean>;
        function DoGetEnumerator: TEnumerator<T>; override;
      public
        Constructor Create(aGetCurrent : TFunc<TAnonEnumerator<T>,T>;
                           aMoveNext : TFunc<TAnonEnumerator<T>,Boolean>);
      end;
    
    implementation
    
    { TEnumerable<T> }
    
    constructor TAnonEnumerable<T>.Create(aGetCurrent: TFunc<TAnonEnumerator<T>, T>;
      aMoveNext: TFunc<TAnonEnumerator<T>, Boolean>);
    begin
      FGetCurrent := aGetCurrent;
      FMoveNext := aMoveNext;
    end;
    
    function TAnonEnumerable<T>.DoGetEnumerator: TEnumerator<T>;
    begin
     result := TAnonEnumerator<T>.Create(FGetCurrent,FMoveNext);
    end;
    
    
    { TAnonEnumerator<T> }
    
    constructor TAnonEnumerator<T>.Create(aGetCurrent: TFunc<TAnonEnumerator<T>, T>;
      aMoveNext: TFunc<TAnonEnumerator<T>, Boolean>);
    begin
      FGetCurrent := aGetCurrent;
      FMoveNext := aMoveNext;
    end;
    
    function TAnonEnumerator<T>.DoGetCurrent: T;
    begin
      result := FGetCurrent(self);
    end;
    
    function TAnonEnumerator<T>.DoMoveNext: Boolean;
    begin
     result := FMoveNext(Self);
    end;
    
    end.
    

    This would allow you declare your Current and MoveNext methods anonymously.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 514k
  • Answers 514k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer Have you emailed Twitter support to get them to turn… May 16, 2026 at 6:12 pm
  • Editorial Team
    Editorial Team added an answer int and Int32 are the same type. No cast is… May 16, 2026 at 6:12 pm
  • Editorial Team
    Editorial Team added an answer it is a little more clear if you use gvim,… May 16, 2026 at 6:12 pm

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Related Questions

Using Delphi 2010 I would like to copy a PNG image to the clipboard
Using Delphi 2010 and a patched version of the BDE I run into a
I am using Delphi 2010 to implement an Application Menu for my ribbon control...
I am using Delphi 2010 and Indy 10 that ships with it. The MemStream
I am using Delphi 7 but I have trialed the Delphi 2005 - 2010
I'm using Delphi (7-2010) and trying to figure out a good way to handle
I'm using Firebird 2.1, DBExpress Driver from DevArt and Delphi 2010. Some of my
As already discussed in Rtti data manipulation and consistency in Delphi 2010 a consistency
I have a Delphi 2010 app which shows/hides the desktop icons under XP fine.
While porting some code from Delphi 7 to Delphi 2010 I was rewriting my

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.