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

  • SEARCH
  • Home
  • 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 7970191
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T07:21:33+00:00 2026-06-04T07:21:33+00:00

I am using Delphi XE to implement an enumerator that allows filtering the elements

  • 0

I am using Delphi XE to implement an enumerator that allows filtering the elements of the list by type. I have quickly assembled a test unit as follows:

unit uTestList;

interface

uses Generics.Collections;

type
  TListItemBase = class(TObject)
  end; { TListItemBase }

  TListItemChild1 = class(TListItemBase)
  end;

  TListItemChild2 = class(TListItemBase)
  end;

  TTestList<T : TListItemBase> = class;

  TOfTypeEnumerator<T, TFilter> = class(TInterfacedObject, IEnumerator<TFilter>)
  private
    FTestList : TList<T>;
    FIndex : Integer;
  protected
    constructor Create(Owner : TList<T>); overload;

    function GetCurrent : TFilter;
    function MoveNext : Boolean;
    procedure Reset;

    function IEnumerator<TFilter>.GetCurrent = GetCurrent;
    function IEnumerator<TFilter>.MoveNext = MoveNext;
    procedure IEnumerator<TFilter>.Reset = Reset;
  end;

  TOfTypeEnumeratorFactory<T, TFilter> = class(TInterfacedObject, IEnumerable)
  private
    FTestList : TList<T>;
  public
    constructor Create(Owner : TList<T>); overload;
    function GetEnumerator : TOfTypeEnumerator<T, TFilter>;
  end;

  TTestList<T : TListItemBase> = class(TList<T>)
  public
    function OfType<TFilter : TListItemBase>() : IEnumerable;
  end; { TTestList }


implementation

{ TOfTypeEnumerator<T, TFilter> }

constructor TOfTypeEnumerator<T, TFilter>.Create(Owner: TList<T>);
begin
  inherited;
  FTestList := Owner;
  FIndex := -1;
end;

function TOfTypeEnumerator<T, TFilter>.GetCurrent: TFilter;
begin
  Result := TFilter(FTestList[FIndex]);
end;

function TOfTypeEnumerator<T, TFilter>.MoveNext: Boolean;
begin
  Inc(FIndex);
  while ((FIndex < FTestList.Count)
         and (not FTestList[FIndex].InheritsFrom(TFilter))) do
  begin
    Inc(FIndex);
  end; { while }
end;

{ TOfTypeEnumeratorFactory<T, TFilter> }

constructor TOfTypeEnumeratorFactory<T, TFilter>.Create(Owner: TList<T>);
begin
  inherited;
  FTestList := Owner;
end;

function TOfTypeEnumeratorFactory<T, TFilter>.GetEnumerator: TOfTypeEnumerator<T, TFilter>;
begin
  Result := TOfTypeEnumerator<T,TFilter>.Create(FTestList);
end;

{ TTestList<T> }

function TTestList<T>.OfType<TFilter>: IEnumerable;
begin
  Result := TOfTypeEnumeratorFactory<T,TFilter>.Create(self);
end;

end.

Compiling this unit fails with the dreaded F2084 Internal Error: D7837. I can certainly do this without an enumerator, but I’d rather have one available to make the code consistent. I had a similar compiler problem when trying to implement this on top of Spring4D, but figured I would put out a plain, vanilla Delphi issue here.

Does anyone have an alternate implementation that actually compiles?

Thanks.

  • 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-06-04T07:21:34+00:00Added an answer on June 4, 2026 at 7:21 am

    You don’t want to use the IEnumerator<T> from System.pas, trust me. That thing brings along so much trouble because it inherits from IEnumerator and so has that GetCurrent method with different results (TObject for IEnumerator and T for IEnumerator<T>).

    Better define your own IEnumerator<T>:

    IEnumerator<T> = interface
      function GetCurrent: T;
      function MoveNext: Boolean;
      procedure Reset;
      property Current: T read GetCurrent;
    end;
    

    Same with IEnumerable. I would say define your own IEnumerable<T>:

    IEnumerable<T> = interface
      function GetEnumerator: IEnumerator<T>;
    end;
    

    If you use that in your TOfTypeEnumerator<T, TFilter> you can remove the method resolution clauses causing the ICE.

    When you do that you will start seeing other compiler errors E2008, E2089 and some more.

    • calling just inherited in your constructor tries to call the constructor with the same signature in your ancestor class which does not exist. So change it to inherited Create.

    • don’t use IEnumerable but use IEnumerable<TFilter> because that is what your want to enumerator over

    • don’t use methods and casts that are only allowed for objects or specify the class constraint on T and TFilter

    • MoveNext needs a Result

    Here is the compiling unit. Did a quick test and it seems to work:

    unit uTestList;
    
    interface
    
    uses
      Generics.Collections;
    
    type
      IEnumerator<T> = interface
        function GetCurrent: T;
        function MoveNext: Boolean;
        property Current: T read GetCurrent;
      end;
    
      IEnumerable<T> = interface
        function GetEnumerator: IEnumerator<T>;
      end;
    
      TOfTypeEnumerator<T: class; TFilter: class> = class(TInterfacedObject, IEnumerator<TFilter>)
      private
        FTestList: TList<T>;
        FIndex: Integer;
      protected
        constructor Create(Owner: TList<T>); overload;
    
        function GetCurrent: TFilter;
        function MoveNext: Boolean;
      end;
    
      TOfTypeEnumeratorFactory<T: class; TFilter: class> = class(TInterfacedObject, IEnumerable<TFilter>)
      private
        FTestList: TList<T>;
      public
        constructor Create(Owner: TList<T>); overload;
        function GetEnumerator: IEnumerator<TFilter>;
      end;
    
      TTestList<T: class> = class(TList<T>)
      public
        function OfType<TFilter: class>: IEnumerable<TFilter>;
      end;
    
    implementation
    
    { TOfTypeEnumerator<T, TFilter> }
    
    constructor TOfTypeEnumerator<T, TFilter>.Create(Owner: TList<T>);
    begin
      inherited Create;
      FTestList := Owner;
      FIndex := -1;
    end;
    
    function TOfTypeEnumerator<T, TFilter>.GetCurrent: TFilter;
    begin
      Result := TFilter(TObject(FTestList[FIndex]));
    end;
    
    function TOfTypeEnumerator<T, TFilter>.MoveNext: Boolean;
    begin
      repeat
        Inc(FIndex);
      until (FIndex >= FTestList.Count) or FTestList[FIndex].InheritsFrom(TFilter);
      Result := FIndex < FTestList.Count;
    end;
    
    { TOfTypeEnumeratorFactory<T, TFilter> }
    
    constructor TOfTypeEnumeratorFactory<T, TFilter>.Create(Owner: TList<T>);
    begin
      inherited Create;
      FTestList := Owner;
    end;
    
    function TOfTypeEnumeratorFactory<T, TFilter>.GetEnumerator: IEnumerator<TFilter>;
    begin
      Result := TOfTypeEnumerator<T, TFilter>.Create(FTestList);
    end;
    
    { TTestList<T> }
    
    function TTestList<T>.OfType<TFilter>: IEnumerable<TFilter>;
    begin
      Result := TOfTypeEnumeratorFactory<T,TFilter>.Create(self);
    end;
    
    end.
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have an application (writted using Delphi 2009) that allows a user to run
We have an application developed using Delphi 5 that we cannot upgrade to Delphi
I'm using Delphi 2007 and I have this case: { CommonUnit.pas } type //
I am using Delphi 2007 and I am trying to make record type file.
I have to implement a communication between my app and another PC using the
I am using Delphi 2010 to implement an Application Menu for my ribbon control...
I am using Delphi 2010 with Tim Anderson's SQLite wrapper (unicode version) Have a
Using delphi 7, I have a TCollection/TCollectionItem set of descendents. They are intended to
I´m using Delphi 5 with SQL Server 2000 here. I have created an ADOQuery
How could i implement Type-Safe Enumerations in Delphi in a COM scenario ? Basically,

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.