Search code examples
delphidelphi-7

Can I directly add record as object in stringlist?


Currently I am adding object by creating it like:

type    
  TRecord = class
  private
    str: string;
    num: Integer;
  public
    constructor Create;
  end;

...

procedure TForm1.Button2Click(Sender: TObject);
var
  i: Integer;
  rec: TRecord;
  Alist: TStringList;
begin
  Alist := TStringList.create;
  Alist.Clear;
  for i := 0 to 9 do 
  begin
    rec := Trecord.Create; //create instance of class
    rec.str := 'rec' + IntToStr(i);
    rec.num := i * 2;
    Alist.AddObject(IntToStr(i), rec);
  end;
end;

Is this method correct or inefficient ? Or Can I directly add object not by creating it like using record?

type    
  PRec = ^TRec;
  TRec = record
    str: string;
    num: Integer;
  end;

...
var
  rec: TRec;
...

for i := 0 to 9 do 
begin
  //how to write here to have a new record, 
  //can i directly Create record in delphi 7 ?
  rec.str := 'rec' + IntToStr(i);
  rec.num := i*2;
  Alist.AddObject(IntToStr(i), ???); // how to write here?
end;

Or other fast and simple way?

I am using Delphi 7.

Thanks in advance.


Solution

  • The way you're doing it now is fine.

    You can't do it with a record without allocating memory when you add a new record to the TStringList.Objects, and you'd have to free it afterwards. You're just as well off using a class as you are now; you have to free the objects before freeing the stringlist. (In more recent versions of Delphi, TStringList has an OwnsObjects property that will auto-free them for you when the stringlist is free'd, but it's not in Delphi 7.)

    If you really want to do this with a record, you can:

    type    
      PRec = ^TRec;
      TRec = record
        str: string;
        num: Integer;
      end;
    
    var
      rec: PRec;
    begin
      for i := 0 to 9 do 
      begin
        System.New(Rec);
        rec.str := 'rec' + IntToStr(i);
        rec.num := i*2;
        Alist.AddObject(IntToStr(i), TObject(Rec)); // how to write here?
      end;
    end;
    

    You'll need to use System.Dispose(PRec(AList.Objects[i])) to release the memory before freeing the stringlist. As I said, the way you're doing it now is actually much easier; you don't have to do the typecast when adding to and deleting from the stringlist.

    You don't need the AList.Clear, by the way. Since you're creating the stringlist, there can't be anything in it to remove.