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:
uni
A worked version using system.IEnumerable and system.IEnumerator
unit uTestList;
interface
uses Generics.Collections;
type
TListItemBase = class(TObject)
end; { TListItemBase }
TListItemChild1 = class(TListItemBase)
end;
TListItemChild2 = class(TListItemBase)
end;
TTestList = class;
TOfTypeEnumerator = class(TInterfacedObject, IEnumerator, IEnumerator)
private
FTestList : TList;
FIndex : Integer;
protected
constructor Create(Owner : TList); overload;
function GetCurrent: TObject;
function GenericGetCurrent : TFilter;
function MoveNext : Boolean;
procedure Reset;
function IEnumerator.GetCurrent = GenericGetCurrent;
end;
TOfTypeEnumeratorFactory = class(TInterfacedObject, IEnumerable, IEnumerable)
private
FTestList : TList;
public
constructor Create(Owner : TList); overload;
function GetEnumerator : IEnumerator;
function GenericGetEnumerator : IEnumerator;
function IEnumerable.GetEnumerator = GenericGetEnumerator;
end;
TTestList = class(TList)
public
function OfType() : IEnumerable;
end; { TTestList }
implementation
{ TOfTypeEnumerator }
constructor TOfTypeEnumerator.Create(Owner: TList);
begin
inherited Create;
FTestList := Owner;
FIndex := -1;
end;
function TOfTypeEnumerator.GenericGetCurrent: TFilter;
begin
Result := TFilter(TObject(FTestList[FIndex]));
end;
function TOfTypeEnumerator.GetCurrent: TObject;
begin
Result := TObject( FTestList[FIndex] );
end;
function TOfTypeEnumerator.MoveNext: Boolean;
begin
repeat
Inc(FIndex);
until (FIndex >= FTestList.Count) or FTestList[FIndex].InheritsFrom(TFilter);
Result := FIndex < FTestList.Count;
end;
procedure TOfTypeEnumerator.Reset;
begin
FIndex := -1;
end;
{ TOfTypeEnumeratorFactory }
constructor TOfTypeEnumeratorFactory.Create(Owner: TList);
begin
inherited Create;
FTestList := Owner;
end;
function TOfTypeEnumeratorFactory.GetEnumerator: IEnumerator;
begin
Result := GenericGetEnumerator;
end;
function TOfTypeEnumeratorFactory.GenericGetEnumerator: IEnumerator;
begin
Result := TOfTypeEnumerator.Create(FTestList);
end;
{ TTestList }
function TTestList.OfType: IEnumerable;
begin
Result := TOfTypeEnumeratorFactory.Create(self);
end;
end.
A test procedure:
var
MyElem: TListItemBase;
MyElem1: TListItemChild1;
MyElem2: TListItemChild2;
begin
Memo1.Clear;
for MyElem in FTestList.OfType() do
begin
Memo1.Lines.Add('----------');
end;
for MyElem1 in FTestList.OfType() do
begin
Memo1.Lines.Add('==========');
end;
for MyElem2 in FTestList.OfType() do
begin
Memo1.Lines.Add('++++++++++');
end;