Delphi 11 中的变体行为是否发生了变化?

Has Variant behavior changed in Delphi 11?

在Delphi 10.3 中,我写了一些Excel 自动化代码。我使用了变体。例程完成后,我清除并释放了变体的 freeAndNil...

  VarClear(arrData);
  FreeAndNil(arrData);

此编译并且 运行 很好。我刚刚升级到 D11,即 Alexandria。此代码现在给出错误。 ...不兼容的类型:TObject 和 Variant。

我将这部分代码重写为:

  VarClear(arrData);
  arrData.Free;

这个编译,乍一看似乎 运行 没问题。这是 clear/dispose of variants in Alexandria 的正确方法吗?

这两个代码片段都是错误的。您不会在变体上调用 Free。您在对象实例上调用 Free。只需删除该行。

FreeAndNil() 的签名确实在 Delphi 10.4 中更改了,确切地说:

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.

首先尝试 Free() 一个 Variant 是错误的。 never 起作用了,never 应该首先出现在您的代码中。根据旧定义,FreeAndNil() 会在 Variant 上调用 TObject.Free(),这是错误的。在您的新代码下,arrData.Free; 将编译,但会在运行时调用方法分派以调用 Excel 对象上不存在的 Free() 方法,这将失败。

所以,完全删除 Free,它不属于这里。在所有 Delphi 版本中,手动将 Variant 重置为默认状态的正确解决方案是将 Variants.Null or Variants.Unassigned 分配给它,例如:

arrData := Null;
arrData := Unassigned;