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
You don't want to use the IEnumerator
Better define your own IEnumerator
IEnumerator = 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
IEnumerable = interface
function GetEnumerator: IEnumerator;
end;
If you use that in your TOfTypeEnumerator
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
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 = interface
function GetCurrent: T;
function MoveNext: Boolean;
property Current: T read GetCurrent;
end;
IEnumerable = interface
function GetEnumerator: IEnumerator;
end;
TOfTypeEnumerator = class(TInterfacedObject, IEnumerator)
private
FTestList: TList;
FIndex: Integer;
protected
constructor Create(Owner: TList); overload;
function GetCurrent: TFilter;
function MoveNext: Boolean;
end;
TOfTypeEnumeratorFactory = class(TInterfacedObject, IEnumerable)
private
FTestList: TList;
public
constructor Create(Owner: TList); overload;
function GetEnumerator: IEnumerator;
end;
TTestList = class(TList)
public
function OfType: IEnumerable;
end;
implementation
{ TOfTypeEnumerator }
constructor TOfTypeEnumerator.Create(Owner: TList);
begin
inherited Create;
FTestList := Owner;
FIndex := -1;
end;
function TOfTypeEnumerator.GetCurrent: TFilter;
begin
Result := TFilter(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;
{ TOfTypeEnumeratorFactory }
constructor TOfTypeEnumeratorFactory.Create(Owner: TList);
begin
inherited Create;
FTestList := Owner;
end;
function TOfTypeEnumeratorFactory.GetEnumerator: IEnumerator;
begin
Result := TOfTypeEnumerator.Create(FTestList);
end;
{ TTestList }
function TTestList.OfType: IEnumerable;
begin
Result := TOfTypeEnumeratorFactory.Create(self);
end;
end.