Реализация перечислителя списка OfType в Delphi

Я использую Delphi XE для реализации перечислителя, который позволяет фильтровать элементы списка по типу. Я быстро собрал тестовый модуль следующим образом:

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.

Компиляция этого модуля завершается с ошибкой F2084 Internal Error: D7837. Я, конечно, могу сделать это без перечислителя, но я бы предпочел, чтобы он был доступен, чтобы сделать код согласованным. У меня была аналогичная проблема с компилятором, когда я пытался реализовать это поверх Spring4D, но решил, что выложу здесь простую, ванильную проблему Delphi.

Есть ли у кого-нибудь альтернативная реализация, которая действительно компилируется?

Спасибо.

21
задан Louis Kleiman 18 May 2012 в 17:54
поделиться