In Delphi 10.3, I had written some Excel automation code. I used variants. When the routine was finished, I cleared and freeAndNil the Variant...
VarClear(arrData);
FreeAndNil(arrData);
This compiled and ran fine. I have just upgraded to D11, i.e. Alexandria. This code now gives an error. ... Incompatible Type: TObject and Variant.
I rewrote this portion of code to be:
VarClear(arrData);
arrData.Free;
This compiles, and at first glance, seems to run fine. Is this the proper way to clear/dispose of variants in Alexandria?
The signature of FreeAndNil()
was indeed changed, in Delphi 10.4, to be exact:
https://blog.marcocantu.com/blog/2020-may-delphi-104-rtl.html
We updated the signature of the FreeAndNil procedure, to avoid its use with interface references and other unsupported data types. It is now declared to require a reference to a TObject:
procedure FreeAndNil(const [ref] Obj: TObject); inline;
This means that incorrect usage of FreeAndNil will now cause a compiler error. In the past, incorrect usage would not be caught, leading to difficult bugs. Note that although the parameter is declared as const, the by-reference variable is indeed modified.
It is wrong to try to Free()
a Variant
in the first place. That has never worked, and should never have been in your code in the first place. Under the old definition, FreeAndNil()
would have called TObject.Free()
on the Variant
, which is wrong. Under your new code, arrData.Free;
will compile, but will invoke method dispatching at runtime to call a non-existent Free()
method on the Excel object, which will fail.
So, just remove the Free
altogether, it doesn't belong here. The correct solution, in all Delphi versions, to manually reset a Variant
to a default state is to assign Variants.Null
or Variants.Unassigned
to it, eg:
arrData := Null;
arrData := Unassigned;