unit gencollection;
{
This unit implements a generic collection
including an automatic generic enumerator.
Some remarks:
Collections derived from TCollection only have an advantage in four ways:
- They are streamable by default since they inherit from TPersistent
- Specializations will show up in the object inspector because of that
- They have built-in change notifications
- And have full RTTI automatically
Otherwise you would simply use a TList<T> as the underlying structure,
because that already has:
- a generic enumerator
- no need to derive from TCollectionItem
- It has Sort(IComparer<T>), IndexOf, Contains, BinarySearch, etc.
- Less internal typecasting necessary.
This unit is Delphi compatible, but written in FreePascal.
Have fun, Thaddy.
}
{$ifdef fpc}{$mode delphi}{$endif}{$M+}
interface
uses classes;
type
TGenericCollectionItem<T> = class(TCollectionItem)
private
FItem: T;
public
property Value: T read FItem write FItem;
end;
TGenericCollectionEnumerator<T> = class
private
FCollection: TCollection;
FPosition: Integer;
public
constructor Create(ACollection: TCollection);// avoids forward
function GetCurrent: TGenericCollectionItem<T>;
function MoveNext: Boolean;
property Current: TGenericCollectionItem<T> read GetCurrent;
end;
TGenericCollection<T> = class(TCollection)
protected
Function GetItem(index:integer):TGenericCollectionItem<T>;
procedure SetItem(Index:integer;Item:TGenericCollectionItem<T>);
public
constructor Create;
function Add: TGenericCollectionItem<T>;
property Items[Index:integer]:TGenericCollectionItem<T> read GetItem write SetItem;default;
function GetEnumerator: TGenericCollectionEnumerator<T>;
end;
implementation
function TGenericCollection<T>.GetItem(Index:integer):TGenericCollectionItem<T>;
begin
Result := TGenericCollectionItem<T>(inherited GetItem(index));
end;
procedure TGenericCollection<T>.SetItem(Index:integer;Item:TGenericCollectionItem<T>);
begin
inherited SetItem(Index,Item)
end;
constructor TGenericCollection<T>.Create;
begin
inherited Create(TGenericCollectionItem<T>);
end;
function TGenericCollection<T>.Add: TGenericCollectionItem<T>;
begin
Result := TGenericCollectionItem<T>(inherited Add);
end;
function TGenericCollection<T>.GetEnumerator:TGenericCollectionEnumerator<T>;
begin
Result := TGenericCollectionEnumerator<T>.Create(self);
end;
constructor TGenericCollectionEnumerator<T>.Create(ACollection: TCollection);
begin
inherited Create;
FCollection := ACollection;
FPosition := -1;
end;
function TGenericCollectionEnumerator<T>.GetCurrent: TGenericCollectionItem<T>;
begin
Result := TGenericCollectionItem<T>(FCollection.Items[FPosition])
end;
function TGenericCollectionEnumerator<T>.MoveNext: Boolean;
begin
Inc(FPosition);
Result := FPosition < FCollection.Count;
end;
end.