Delphi Sent TObjectList like var parameter

577 Views Asked by At

I have class

TFolder = class
    NODE_INDEX: Integer;
    FIRST_INDEX : Integer;
    CODE_NAME: AnsiString;
    NAME: AnsiString;

    constructor Create(NewNODE_INDEX, NewFIRST_INDEX: Integer; NewCODE_NAME, NewNAME: AnsiString);
    destructor Destroy; override;

  end;

And i have Type

type
  TFolderList = class (TObjectList<TFolder>)
  end;

Then i try to use this type

TAccount = class
  ...
  FOLDERS: TFolderList;
public
  constructor Create(...);
  destructor Destroy; override;

  procedure LoadFoldersFromDisk(var _objectList: TFolderList);
end;

When i try to send my TObject list like parameter

procedure TForm1.FormCreate(Sender: TObject);
begin 
  olLOCALFolders := TObjectList<TFolder>.Create();
  Account.LoadFoldersFromDisk(olLOCALFolders);
end;

I get error "Types of actual and formal var parameters must be identical". What I'm doing wrong?

2

There are 2 best solutions below

0
ain On BEST ANSWER

Just replace the TObjectList<TFolder> wtih the TFolderList you defined eariler:

procedure TForm1.FormCreate(Sender: TObject);
begin 
  olLOCALFolders := TFolderList.Create();
  Account.LoadFoldersFromDisk(olLOCALFolders);
end;

However, you probably do not need to use var parameter here - the method name LoadFoldersFromDisk suggest that the method will populate the list sent as parameter with items, and for that you can send the list by value. You only need to use var parameter if the method would alert the list object's memory location (as opposed to it's content), ie when the LoadFoldersFromDisk could free the original list and create new one.

0
David Heffernan On

The error is because your sub-class is a new type, distinct from TObjectList<TFolder> and hence the error.

It is probably a mistake to derive a sub-class like this:

type
  TFolderList = class (TObjectList<TFolder>)
  end;

Doing so forces all parties to use that type and denies you the opportunity to take advantage of generic type compatibility. If you have a generic method operating on TObjectList<T> then your new type would be incompatible.

Instead declare an alias:

type
  TFolderList = TObjectList<TFolder>;

The point about an alias is that it is a different name for the same type as opposed to a new type which your code declares.

Or simply use TObjectList<TFolder> everywhere without declaring TFolderList.

More broadly your TFolder type seems more suited to be a value type. I think it may be better as a record rather than a class.

Further, a var parameter appears incorrect. You would use a var parameter if the function was going to modify the reference. But it is going to populate the list that is passed in by the caller. You should remove the var from the argument list.