Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add records of type record to a TList<>?

Tags:

delphi

tlist

I have a treelist of data. I'm looping through the tree list to match certain records and adding them to a generic TList<>. This works except all record values become the last one added for all items in the TList.

Here's some code:

type
  TCompInfo = record
  private
    class var
      FCompanyName    : string;
      FCompanyPath    : string;
      FCompanyDataPath: string;
      FCompanyVer     : string;
  public
    class procedure Clear; static;
    class property CompanyName : string read FCompanyName write FCompanyName;
    class property CompanyPath : string read FCompanyPath write FCompanyPath;
    class property CompanyDataPath : string read FCompanyDataPath write FCompanyDataPath;
    class property CompanyVer : string read FCompanyVer write FCompanyVer;
  end;
  TCompList = TList<TCompInfo>;

// variablies defined ...
var
  CompData : TCompData;
  AList : TCompList;

Adding records like this:

  tlCompanyList.GotoBOF;
  for i := 0 to tlCompanyList.Count-1 do
  begin
    if colCompanyChecked.Value then
    begin
      inc(ItemsChecked);
      CompData.CompanyName := colCompanyName.Value;
      CompData.CompanyDataPath := colCompanyDataPath.Value;
      CompData.CompanyPath := colCompanyPath.Value;
      CompData.CompanyVer := colCompanyVersion.Value;
      AList.Add(CompData);
  end;
  tlCompanyList.GotoNext;

...or adding records like this:

  tlCompanyList.GotoBOF;
  for i := 0 to tlCompanyList.Count-1 do
  begin
    if colCompanyChecked.Value then
    begin
      inc(ItemsChecked);
      AList.Count := ItemsChecked;
      AList.Items[ItemsChecked-1].CompanyName := colCompanyName.Value;
      AList.Items[ItemsChecked-1].CompanyDataPath := colCompanyDataPath.Value;
      AList.Items[ItemsChecked-1].CompanyPath := colCompanyPath.Value;
      AList.Items[ItemsChecked-1].CompanyVer := colCompanyVersion.Value;
  end;
  tlCompanyList.GotoNext;

Results in the exact same thing. AList.Items[0...Count-1] all have the same values. Stepping through the code I can see the correct data is being captured but once I save a new record to AList all previous records take on the same values. This shows me that each item in the TList is a pointer to the same record in memory. If the memory the record is taking changes all items will change. This make since but is not what I want. How do I allocate for new records in a TList to hold different data?

I know I can accomplish the end result in other ways and indeed I have. This has become more of an educational thing for me now using generics and records. I am using Delphi XE.

Thanks

like image 781
jwilfong Avatar asked Dec 13 '22 11:12

jwilfong


1 Answers

You have declared all the fields of the record as "class var". In a class a "class var"'s value is the same for all instances of the class. Actually I never used "class var" with records, but I guess that the semantic is the same for record types too. Meaning that whenever you change the value of the field in one record, it will change in all existent records.

Try it without "class var" and simple "property" instead of "class property".

like image 186
Toto Avatar answered Jan 13 '23 08:01

Toto