I want to create a TObjectList<T> descendant to handle common functionality between object lists in my app. Then I want to further descend from that new class to introduce additional functionality when needed. I cannot seem to get it working using more than 1 level of inheritance. I probably need to understand generics a little bit more, but I've search high and low for the correct way to do this without success. Here is my code so far:
unit edGenerics; interface uses Generics.Collections; type TObjectBase = class public procedure SomeBaseFunction; end; TObjectBaseList<T: TObjectBase> = class(TObjectList<T>) public procedure SomeOtherBaseFunction; end; TIndexedObject = class(TObjectBase) protected FIndex: Integer; public property Index: Integer read FIndex write FIndex; end; TIndexedObjectList<T: TIndexedObject> = class(TObjectBaseList<T>) private function GetNextAutoIndex: Integer; public function Add(AObject: T): Integer; function ItemByIndex(AIndex: Integer): T; procedure Insert(AIndex: Integer; AObject: T); end; TCatalogueItem = class(TIndexedObject) private FID: integer; public property ID: integer read FId write FId; end; TCatalogueItemList = class(TIndexedObjectList<TCatalogueItem>) public function GetRowById(AId: Integer): Integer; end; implementation uses Math; { TObjectBase } procedure TObjectBase.SomeBaseFunction; begin end; { TObjectBaseList<T> } procedure TObjectBaseList<T>.SomeOtherBaseFunction; begin end; { TIndexedObjectList } function TIndexedObjectList<T>.Add(AObject: T): Integer; begin AObject.Index := GetNextAutoIndex; Result := inherited Add(AObject); end; procedure TIndexedObjectList<T>.Insert(AIndex: Integer; AObject: T); begin AObject.Index := GetNextAutoIndex; inherited Insert(AIndex, AObject); end; function TIndexedObjectList<T>.ItemByIndex(AIndex: Integer): T; var I: Integer; begin Result := Default(T); while (Count > 0) and (I < Count) and (Result = Default(T)) do if Items[I].Index = AIndex then Result := Items[I] else Inc(I); end; function TIndexedObjectList<T>.GetNextAutoIndex: Integer; var I: Integer; begin Result := 0; for I := 0 to Count - 1 do Result := Max(Result, Items[I].Index); Inc(Result); end; { TCatalogueItemList } function TCatalogueItemList.GetRowById(AId: Integer): Integer; var I: Integer; begin Result := -1; for I := 0 to Pred(Self.Count) do if Self.Items[I].Id = AId then begin Result := I; Break; end; end; end. /////// ERROR HAPPENS HERE ////// ???? why is beyond me It appears that the following declaration:
>>> TCatalogueItemList = class(TIndexedObjectList<TCatalogueItem>) <<<< causes the following compiler error:
[DCC Error] edGenerics.pas(106): E2010 Incompatible types: 'TCatalogueItem' and 'TIndexedObject'
However the compiler shows the error at the END of the compiled unit (line 106), not on the declaration itself, which does not make any sense to me...
Basically the idea is that I have a generic list descending from TObjectList that I can extend with new functionality on an as needs basis. Any help with this would be GREAT!!!
I should add, using Delphi 2010.
Thanks.
// error happens hereor//this is line 106would suffice.TIndexedObjectList<T: TIndexedObject>descend fromTObjectBaseList<T: TObjectBase>and not fromTObjectList<T>as in your current code?