Warm tip: This article is reproduced from stackoverflow.com, please click
delphi

Compile time error in assignment statement

发布于 2020-04-13 10:37:24

I have this code:

TTimer(TimerList.Items[Row]) := TTimer.Create(Self);

When I run the program, there is the following error:

unit1.pas(70,19) Error: Argument cannot be assigned to

Why is this error thrown and how can I fix it?

Questioner
DelPhi1
Viewed
73
J... 2020-02-04 04:16

You're including an explicit typecast on the left hand side - this can be allowed for variables, but here Items is a property accessed via a getter and so it is not a variable but a function result. The only place you can typecast here, if needed, is on the right hand side of the assignment.

We don't know the type of TimerList, but assuming it is a compatible type like TList<TTimer> you can just assign it directly.

 TimerList.Items[Row] := TTimer.Create(Self);

If the list or array has elements of a different, compatible, but not implicitly type-castable type then you would typecast the right hand side of the assignment to match the expected type of the left hand side.


In the case of a plain TObjectList (from comments) the list elements are plain TObject, so any object, including a TTimer can be assigned to the list element as above. Where you would need to typecast is going the other way - assigning the TObject back to a TTimer variable :

var 
  LMyTimer : TTimer
begin
  LMyTimer := TTimer(TimerList.Items[someIndex]);

Also be careful that in creating the object with TTimer.Create(self) you are giving self (probably the form?) ownership of the timer object. By placing it into a TObjectList you are then also giving ownership of the object to the list. Both will try to free the object when they are themselves freed - whichever one does so last will cause a crash, so this is a bug.

Decide which object will have ownership responsibility and implement that - an object should not have two owners! Either have the TObjectList own the timer, and therefore create it with TTimer.Create(nil), or leave the ownership with the (form?) using TTimer.Create(self) and use a plain TList instead of a TObjectList.

If you have a modern version of Delphi, I would strongly prefer a typed generic list, either TList<TTimer> or TObjectList<TTimer>. This gets around the need to typecast entirely.