-1

I am using generics to define a list of objects that themselves hold generic lists. I have written a method for retrieving the aggregate of each of these lists using specific methods that basically do the same thing. Below is the structure:

unit Unit1;

interface

uses
 System.Generics.Collections;

type
  TListType=(ltSType,ltFType);

  TMyList<T> = class(TList<T>)
   {Do some stuff in here to help load lists etc}
  end;

  TListObject=class(TObject)
  private
    FSList:TMyList<string>;
    FIList:TMyList<integer>;
    function GetSList: TMyList<string>;
    function GetIList: TMyList<integer>;
  public
    property MySList:TMyList<string> read GetSList;
    property MyIList:TMyList<integer> read GetIList;
    constructor create;
  end;

  TListOfObject<T:TListObject> = class(TObjectList<T>)
  public
    Function AggrSList:TMyList<string>;
    Function AggrIList:TMyList<integer>;
  end;

implementation

{ TListObject }

constructor TListObject.create;
begin
  FSList:=TMyList<string>.create;
  FIList:=TMyList<integer>.create;
end;

function TListObject.GetIList: TMyList<integer>;
begin
  result:=FIlist;
end;

function TListObject.GetSList: TMyList<string>;
begin
  result:=FSList;
end;


{ TListOfObject<T> }

function TListOfObject<T>.AggrIList: TMyList<integer>;
var
  i,j:integer;

begin
  result:=TMyList<integer>.create;
  for I := 0 to count-1 do
    for j := 0 to items[i].MyIList.Count-1 do
      result.Add(items[i].MyIList[j]);
end;

function TListOfObject<T>.AggrSList: TMyList<string>;
var
  i,j:integer;
begin
  result:=TMyList<string>.create;
  for I := 0 to count-1 do
    for j := 0 to items[i].MySList.Count-1 do
      result.Add(items[i].MySList[j]);
end;

end.

I am still fairly new to generics but feel that the aggregate methods AggrIList and AggrSlist could be written using generics that uses a single method to extract the data then is cast at the result.

Is this possible and how would I approach this? I plan to do some more advanced functions that would benefit from this approach as well.

LU RD
  • 34,438
  • 5
  • 88
  • 296
cheechaway
  • 101
  • 1
  • 10
  • Check documentation ... http://docwiki.embarcadero.com/CodeExamples/XE7/en/Generics_Collections_TObjectList_(Delphi). You can use TObjectList, you don't need to make it so difficult as in your example. Or you can use simple TList with records ... http://stackoverflow.com/questions/5797368/delphi-tlist-of-records. – smooty86 Mar 31 '15 at 06:40

1 Answers1

0

You can use (pseudocode):

TNestedList<T> = class(TList<TList<T>>)
  function GetAggregateList : TList<T>;
end;

function TNestedList<T>.GetAggregateList : TList<T>;

var
  List : TList<T>;
  Item : T;

begin
  Result := TList<T>.Create;
  for List in Self do
    for Item in List do
      Result.Add(Item);
  end;

No need to implement GetAggregateList for specific types - that's what you use generics for.

Also note that it might be better to either call your method CreateAggregateList (to make clear that the caller is responsible for destroying the created list) or to pass in an already created list instance into a procedure:

procedure GetAggregateList(List : TList<T>);

...which leaves list ownership completely to the caller and is quite a common pattern in Delphi.

jpfollenius
  • 16,456
  • 10
  • 90
  • 156
  • Thanks, I think this approach will do just fine. I have to do some recursive operations which will be ok in this type of structure. – cheechaway Apr 01 '15 at 01:59